davilk vm中new的策略

dalvik 虚拟机中, new 操作符最终对应 dvmAllocObject 这个 C 函数。下面通过伪码的形式列出 dvmAllocObject 的实现。
Object*dvmAllocObject(ClassObject *clazz, int flags) {
        n = get object size form class object clazz
        first try: allocate n bytes from heap
        if first try failed {
                run garbage collector without collecting soft references
                second try: allocate n bytes from heap
        }
        if second try failed {
                third try: grow the heap and allocate n bytes from heap
                ( 注释:堆是虚拟内存,一开始并未分配所有的物理内存,只要还没有达到虚拟内存的最大值,可以通过获取更多物理内存的方式来扩展堆 )
        }
        if third try failed {
                run garbage collector with collecting soft references
                fourth try: grow the hap and allocate n bytes from heap
        }
        if fourth try failed, return null pointer, dalvik vm will abort
}

可以看出,为了分配内存,虚拟机尽了最大的努力,做了四次尝试。其中进行了两次垃圾收集,第一次不收集 SoftReference ,第二次收集 SoftReference 。从中我们也可以看出垃圾收集的时机,实质上在 dalvik 虚拟机实现中有 3 个时机可以触发垃圾收集的运行:
1 )程序员显式的调用 System.gc()
2 )内存分配失败时

3)如果分配的对象大小超过384KB,运行并发标记(concurrent mark)


dalvik虚拟机实现中,是通过底层的bionicC库的malloc/free操作来分配/释放内存的。bionicC库的malloc/free操作是基于DougLea的实现(dlmalloc),这是一个被广泛使用,久经考验的C内存管理库。

在虚拟机中维护了两个对应于堆内存的位图,称为liveBitsmarkBits

在对象布局中,我们看到对象最小占用8个字节。在为对象分配内存时要求必须8字节对齐。这也就是说,对象的大小会调整为8字节的倍数。比如说一个对象的实际大小是13字节,但是在分配内存的时候分配16字节。因此所有对象的起始地址一定是8字节的倍数。堆内存位图就是用来描述堆内存的,每一个bit描述8个字节,因此堆内存位图的大小是对的64分之一。对于MIUI的实现来说,这两个位图各占1M

你可能感兴趣的:(c,虚拟机,object,null,Class,扩展)