GC运行太频繁

时间:2013-06-07 13:49:58

标签: android google-maps memory-leaks garbage-collection

这是一个普遍的问题。 在我的应用程序中,垃圾收集器运行得太频繁(每秒几次)并且不会释放大量内存(小于1Mb)。 问题是,堆大小不再增长。其他手机需要大约40Mb,有时甚至60Mb,应用程序的最大值为128Mb(Galaxy S4)或196Mb(Nexus 4)。

为什么GC经常运行?

当GC运行得太频繁时,下面是logcat的一部分。申请冻结了。我什么都不做,我只是想缩放地图。

06-07 16:50:52.003: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60015K/72980K, paused 51ms, total 51ms
06-07 16:50:52.053: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60016K/72980K, paused 51ms, total 51ms
06-07 16:50:52.113: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60016K/72980K, paused 52ms, total 52ms
06-07 16:50:52.163: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60017K/72980K, paused 52ms, total 52ms
06-07 16:50:52.213: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60017K/72980K, paused 51ms, total 52ms
06-07 16:50:52.273: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60018K/72980K, paused 51ms, total 51ms
06-07 16:50:52.324: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60018K/72980K, paused 51ms, total 51ms
06-07 16:50:52.374: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60019K/72980K, paused 52ms, total 52ms
06-07 16:50:52.434: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60019K/72980K, paused 53ms, total 53ms
06-07 16:50:52.484: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60020K/72980K, paused 52ms, total 52ms
06-07 16:50:52.544: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60020K/72980K, paused 56ms, total 56ms
06-07 16:50:52.594: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60021K/72980K, paused 52ms, total 52ms
06-07 16:50:52.654: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60021K/72980K, paused 52ms, total 52ms
06-07 16:50:52.704: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60022K/72980K, paused 52ms, total 52ms
06-07 16:50:52.754: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60022K/72980K, paused 52ms, total 52ms
06-07 16:50:52.814: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60023K/72980K, paused 52ms, total 52ms
06-07 16:50:52.864: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 6023K/72980K, paused 51ms, total 51ms
06-07 16:50:52.924: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60024K/72980K, paused 55ms, total 56ms
06-07 16:50:52.974: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60024K/72980K, paused 52ms, total 52ms
06-07 16:50:53.024: D/dalvikvm(26176): GC_FOR_ALLOC freed 256K, 18% free 60025K/72980K, paused 52ms, total 52ms

3 个答案:

答案 0 :(得分:3)

您的问题与Google Maps Android API的工作原理以及您的应用分配了多少内存有关。

40-60 MB可能会有问题,因为执行单个GCollection需要更长的时间。作为旁注:我注意到,当有5 MB时,分配15 MB时,添加1000个标记会花费更长的时间。

除此之外,对Google Play Services API的每次调用都在进行IPC,而IPC则根据this answer强制执行GC。在平移或缩放时可能会进行此类IPC调用。

最好将内存占用率降低一些。

答案 1 :(得分:0)

GC在需要时运行。一般来说,(甚至在DVM上)当它需要运行时,它确实比你更了解。如果您将此问题定为GC的问题,但是作为应用程序内存的问题,它可能会帮助您找到解决方案。

频繁发生GC的最可能原因是你几乎没有记忆。例如,如果您分配了大量短期对象,则可能会发生这种情况:您可以快速分配它们,但也可以快速忘记它们。每次GC运行时,它都会成功恢复足够的内存以便应用程序继续...但同样快,您再次填充内存。

如果这实际上是发生了什么,那么,如果你有更多的内存,正如@parry建议的那样,你只会延迟问题。 GC的发生频率较低,但运行时间较长(因为它们会收集更多的垃圾)。这可能就足够了,但可能不是。

检查您是否在经常调用的例程中分配对象(例如,绘制例程)。

答案 2 :(得分:-2)

如果您认为GC的行为很愚蠢(很可能),并且VM有更多的内存可供使用,那么您可以尝试强制它通过要求一次性1/5/10 MB分配来增加堆大小(用OOME的try-catch保护它)。 这可能会导致GC在每个循环中进行更多清理,或者增加完整GC发生的可能性 另一种在PC上运行的启发式方法是在循环中调用System.GC()x次以触发完整的GC。
总而言之,我自己也遇到过它而且很糟糕。