简体   繁体   English

Android Dalvik VM Logcat

[英]Android Dalvik VM Logcat

Can anyone explain the below Logcat message : 谁能解释以下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

In older versions of Android, certain bits of native framework code would tell the VM about native allocations. 在较旧的Android版本中,某些本机框架代码会告诉VM有关本机分配的信息。 This "external allocation" mechanism was an ugly hack introduced so that native allocations would cause the Dalvik VM to do a garbage collection pass. 这种“外部分配”机制是引入的一个丑陋的hack,因此本机分配将导致Dalvik VM执行垃圾收集过程。

The basic problem was that the Java-language Bitmap object used native memory for the pixel storage. 基本问题是Java语言位图对象使用本机内存进行像素存储。 Because the managed-heap objects were tiny, and the native-heap objects were large, you could allocate tons of Bitmaps without causing a GC. 因为托管堆对象很小,而本机堆对象很大,所以您可以分配大量的位图而不会引起GC。 This was causing apps to bloat up and the system to slow down. 这导致应用膨胀,系统速度变慢。

So, "external allocations" were introduced. 因此,引入了“外部分配”。 Whenever the pixel storage for a Bitmap was allocated on the native heap, an equal amount of memory was deducted from the managed heap. 只要在本机堆上分配了位图的像素存储,就会从托管堆中扣除相等数量的内存。 The idea is that, if your heap is filling up with no-longer-reference bitmaps, you'll run out of managed heap space and the GC will fire. 这个想法是,如果您的堆中填充了不再引用的位图,则会用完托管堆空间,并且GC将触发。

(Unfortunately the GC can't actually release the native storage -- you need to run a finalizer to do that, and finalizers run in a separate pass after the GC completes. For a while the native objects were also holding on to some additional managed-heap objects, so you'd have to GC + finalize + GC to actually clean everything up.) (不幸的是,GC实际上无法释放本机存储-您需要运行终结器来完成此操作,终结器在GC完成后以单独的方式运行。有一段时间,本机对象还保留着一些其他托管对象-heap对象,因此您必须进行GC +最终确定+ GC才能真正清除所有内容。)

My "favorite" part about external allocations is that the API was a simple "increase by N" / "decrease by N", which meant there was no way to associate the native heap with a managed heap object, or check for leaks. 我对外部分配的“最喜欢的”部分是该API是简单的“按N递增” /“按N递减”,这意味着无法将本机堆与托管堆对象关联或检查泄漏。 Because all of the information about the Bitmap was kept in the native object, you couldn't even guess at how much native storage was needed, so it was impossible to look at an hprof dump and figure out how much memory a Bitmap was actually using. 因为有关位图的所有信息都保存在本机对象中,所以您甚至无法猜测需要多少本机存储,因此无法查看hprof转储并弄清楚位图实际使用了多少内存。 。

In Android 3.0 ("Honeycomb") the pixel storage was moved onto the managed heap, and the external allocation mechanism was removed. 在Android 3.0(“ Honeycomb”)中,像素存储移至托管堆上,并且外部分配机制已删除。

So, what the log message in your question means is: some code, probably Bitmap, wanted to allocate 2.5MB of native heap, but that would exceed the VM's external allocation heap limit. 因此,您的问题中的日志消息的含义是:某些代码(可能是Bitmap)想要分配2.5MB的本机堆,但这将超出VM的外部分配堆限制。 You need to figure out what's eating up 20MB of external allocation storage and release some of it. 您需要弄清楚正在占用20MB的外部分配存储空间,然后释放其中的一些空间。

The only way to get information about external allocations is by watching the event log. 获取有关外部分配的信息的唯一方法是查看事件日志。 A few years back I threw a script together ( gclog.py -- was in AOSP dalvik/tools for a while). 几年前,我把一个脚本放在一起( gclog.py-在AOSP dalvik / tools中有一段时间了)。 I have no idea if it will still do anything useful. 我不知道它是否还会做任何有用的事情。 I talk about how to use it in this old thread . 我谈论如何在这个旧线程中使用它。

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

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