繁体   English   中英

Android Dalvik VM Logcat

[英]Android Dalvik VM Logcat

谁能解释以下Logcat消息:

D/dalvikvm(4440): GC_EXTERNAL_ALLOC freed 338K, 47% free 6427K/11911K, external 20418K/22446K, paused 53ms
E/dalvikvm-heap(4440): 2519424-byte external allocation too large for this process.
D/dalvikvm(4440): GC_FOR_MALLOC freed <1K, 47% free 6427K/11911K, external 20398K/22446K, paused 40ms
E/GraphicsJNI(4440): VM won't let us allocate 2519424 bytes

在较旧的Android版本中,某些本机框架代码会告诉VM有关本机分配的信息。 这种“外部分配”机制是引入的一个丑陋的hack,因此本机分配将导致Dalvik VM执行垃圾收集过程。

基本问题是Java语言位图对象使用本机内存进行像素存储。 因为托管堆对象很小,而本机堆对象很大,所以您可以分配大量的位图而不会引起GC。 这导致应用膨胀,系统速度变慢。

因此,引入了“外部分配”。 只要在本机堆上分配了位图的像素存储,就会从托管堆中扣除相等数量的内存。 这个想法是,如果您的堆中填充了不再引用的位图,则会用完托管堆空间,并且GC将触发。

(不幸的是,GC实际上无法释放本机存储-您需要运行终结器来完成此操作,终结器在GC完成后以单独的方式运行。有一段时间,本机对象还保留着一些其他托管对象-heap对象,因此您必须进行GC +最终确定+ GC才能真正清除所有内容。)

我对外部分配的“最喜欢的”部分是该API是简单的“按N递增” /“按N递减”,这意味着无法将本机堆与托管堆对象关联或检查泄漏。 因为有关位图的所有信息都保存在本机对象中,所以您甚至无法猜测需要多少本机存储,因此无法查看hprof转储并弄清楚位图实际使用了多少内存。 。

在Android 3.0(“ Honeycomb”)中,像素存储移至托管堆上,并且外部分配机制已删除。

因此,您的问题中的日志消息的含义是:某些代码(可能是Bitmap)想要分配2.5MB的本机堆,但这将超出VM的外部分配堆限制。 您需要弄清楚正在占用20MB的外部分配存储空间,然后释放其中的一些空间。

获取有关外部分配的信息的唯一方法是查看事件日志。 几年前,我把一个脚本放在一起( gclog.py-在AOSP dalvik / tools中有一段时间了)。 我不知道它是否还会做任何有用的事情。 我谈论如何在这个旧线程中使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM