-
Notifications
You must be signed in to change notification settings - Fork 56
关于垃圾回收
Cthulhu edited this page Apr 16, 2018
·
2 revisions
垃圾回收只有在所有线程到达安全点时才会进行。 现在的安全点全部位于CodeExecution::invoke*()
方法末尾
垃圾回收器使用标记清除算法
(未来可能支持其它..)。
markAndSweep()
首先stop the world
,防止有新引用产生/消失。
接下来:
future<void> stackMarkFuture, localMarkFuture;
for(auto frame = frames.cbegin();frame!=frames.cend();++frame) {
stackMarkFuture = gcThreadPool.submit([this,frame]()->void {
for (auto stackSlot = (*frame)->stack.cbegin(); stackSlot != (*frame)->stack.cend(); ++stackSlot) {
this->mark(*stackSlot);
}
});
localMarkFuture = gcThreadPool.submit([this, frame]()->void {
for (auto localSlot = (*frame)->locals.cbegin(); localSlot != (*frame)->locals.cend(); ++localSlot) {
this->mark(*localSlot);
}
});
}
future<void> staticFieldsFuture = gcThreadPool.submit([this]()->void{
for(auto c: yrt.ma->classTable) {
std::for_each(c.second->sfield.cbegin(), c.second->sfield.cend(),
[this](const pair<size_t, JType*>& offset){
if(typeid(*offset.second)==typeid(JObject)) {
objectBitmap.insert(offset.first);
}else if(typeid(*offset.second)==typeid(JArray)) {
arrayBitmap.insert(offset.first);
}
});
}
});
提交三个并发mark()
任务,第一个第二个任务代表GC root之一:调用栈(包括native 栈),第三个任务包括另一个:类静态字段
接下来垃圾回收线程阻塞,直到标记任务全部完成:
staticFieldsFuture.get();
if(!frames.empty()) {
stackMarkFuture.get();
localMarkFuture.get();
}
sweep()
表示清除阶段,他会清除未被标记的对象,数组,monitor。注意这里由于设计原因,对象内置锁由一个独立的map表示,所以也需要清理他。
void ConcurrentGC::sweep(){
future<void> objectFuture = gcThreadPool.submit([this]()->void{
for (auto pos = yrt.jheap->objheap.begin(); pos != yrt.jheap->objheap.end();) {
// If we can not find active object in object bitmap then clear it
// Notice that here we don't need to lock objectBitmap since it must
// be marked before sweeping
if (objectBitmap.find(pos->first) == objectBitmap.cend()) {
yrt.jheap->objheap.erase(pos++);
}
else {
++pos;
}
}
});
future<void> arrayFuture = gcThreadPool.submit([this]()->void {
for (auto pos = yrt.jheap->arrheap.begin(); pos != yrt.jheap->arrheap.end();) {
// DITTO
if (arrayBitmap.find(pos->first) == arrayBitmap.cend()) {
for (size_t i = 0; i < pos->second.first; i++) {
delete pos->second.second[i];
}
delete[] pos->second.second;
yrt.jheap->arrheap.erase(pos++);
}
else {
++pos;
}
}
});
future<void> monitorFuture = gcThreadPool.submit([this]()->void {
// DITTO
for (auto pos = yrt.jheap->monitorheap.begin(); pos != yrt.jheap->monitorheap.end();) {
if (objectBitmap.find(pos->first) == objectBitmap.cend() || arrayBitmap.find(pos->first) == arrayBitmap.cend()) {
yrt.jheap->monitorheap.erase(pos++);
}
else {
++pos;
}
}
});
}
清除阶段完成后,重置位图,然后resume the world
objectFuture.get();
arrayFuture.get();
monitorFuture.get();
resumeTheWorld();