dvmAllocObject -> dvmMalloc->tryMalloc
static void *tryMalloc(size_t size)
{
void *ptr;
......
ptr = dvmHeapSourceAlloc(size);
调用函数dvmHeapSourceAlloc在Java堆上分配指定大小的内存。如果分配成功,那么就将分配得到的地址直接返回给调用者了。函数dvmHeapSourceAlloc在不改变Java堆当前大小的前提下进行内存分配,这是属于轻量级的内存分配动作。
if (ptr != NULL) {
return ptr;
}
if (gDvm.gcHeap->gcRunning) {
......
dvmWaitForConcurrentGcToComplete();
等待gc完成
} else {
......
gcForMalloc(false);
如果上一步内存分配失败,这时候就需要执行一次GC了。不过如果GC线程已经在运行中,即gDvm.gcHeap->gcRunning的值等于true,那么就直接调用函数dvmWaitForConcurrentGcToComplete等到GC执行完成就是了。否则的话,就需要调用函数gcForMalloc来执行一次GC了,参数false表示不要回收软引用对象引用的对象。
}
ptr = dvmHeapSourceAlloc(size);
再次调用函数dvmHeapSourceAlloc尝试轻量级的内存分配操作。如果分配成功,那么就将分配得到的地址直接返回给调用者了。
if (ptr != NULL) {
return ptr;
}
ptr = dvmHeapSourceAllocAndGrow(size);
如果上一步内存分配失败,这时候就得考虑先将Java堆的当前大小设置为Dalvik虚拟机启动时指定的Java堆最大值,再进行内存分配了。这是通过调用函数dvmHeapSourceAllocAndGrow来实现的。
如果调用函数dvmHeapSourceAllocAndGrow分配内存成功,则直接将分配得到的地址直接返回给调用者了。
if (ptr != NULL) {
......
return ptr;
}
gcForMalloc(true);
如果上一步内存分配还是失败,这时候就得出狠招了。再次调用函数gcForMalloc来执行GC。参数true表示要回收软引用对象引用的对象。
ptr = dvmHeapSourceAllocAndGrow(size);
GC执行完毕,再次调用函数dvmHeapSourceAllocAndGrow进行内存分配。这是最后一次努力了,成功与事都到此为止。
if (ptr != NULL) {
return ptr;
}
......
return NULL;
}
