一般来说,Java虚拟机要求支持verbosegc选项,输出详细的垃圾收集调试信息。Dalvik虚拟机可以接受verbosegc选项,然后什么都不做。Dalvik虚拟机使用自己的一套日志机制来输出调试信息。
如果在Linux下运行adb logcat命令,会看到输出如下信息:
(1)D/dalvikvm:表示由Dalvik虚拟机输出的调试信息,括号后的数字代表Dalvik虚拟机所在进程的pid。GC_CONCURRENT有以下几种表示触发垃圾收集的原因。
GC_MALLOC:内存分配失败时触发。
GC_CONCURRENT:当分配的对象大小超过384KB时触发。
GC_EXPLICIT:对垃圾收集的显式调用(System.gc)。
GC_EXTERNAL_ALLOC:外部内存分配失败时触发。
(2)freed 199K:表示本次垃圾收集释放了199KB的内存。
(3)53%free 3023KB/6343KB:其中6343KB表示当前内存总量,3023KB表示可用内存,53%表示可用内存占总内存的比例。(www.daowen.com)
(4)external 0KB/0KB:表示可用外部内存/外部内存总量。
(5)paused 2ms+2ms:第一个时间值表示markrootset的时间,第二个时间值表示第二次Mark的时间。如果触发原因不是GC_CONCURRENT,则这一行为单个时间值,表示垃圾收集的耗时时间。
由此可以得出如下三个结论:
(1)虽然Dalvik虚拟机提供了一些调试信息,但是还缺乏一些关键信息,比如说Mark和Sweep的时间这些调试信息和内存分配息息相关,其中分配内存失败的原因有很多。在分配时不但要明确设置分配多大的内存,并且对于SoftReference、WeakReference和PhantomReference的处理来说,需要明确每次垃圾收集处理了多少个这些引用。
(2)目前Dalvik所有线程共享一个内存堆,这样在分配内存时必须在线程之间互斥,可以考虑为每个内存分配一个线程局部存储堆,一些小的内存分配可以直接从该堆中分配而无须互斥锁。
(3)Dalvik虚拟机中引入了concurrentmark,但是对于多核CPU,可以实现parrelmark,即可以使用多个线程同时运行Mark阶段。
这些都是目前Dalvik虚拟机内存管理可以做出的改进。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。