这是一个一般性的问题。在我的应用程序中,垃圾收集器运行得太频繁(每秒运行几次),并且没有释放大量内存(小于1Mb)。问题是,堆大小不再增长。它大约需要40Mb,在其他手机上有时是60Mb,而一个应用程序的最大容量是128Mb (Galaxy S4)或196Mb (Nexus4)。
为什么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发布于 2013-06-08 04:46:05
您的问题与Google Maps Android API如何工作以及您的应用程序分配了多少内存有关。
40-60 MB可能会有问题,因为执行单个GCollection需要更长的时间。作为附注:我注意到,当分配了15MB时,添加1000个标记所需的时间比分配了5MB时要长得多。
除此之外,每个对Google Play Services的调用都在执行进程间通信,这反过来又会强制根据this answer进行GC。这样的IPC调用可能是在平移或缩放时完成的。
最好将内存占用量保持在较低的水平。
发布于 2013-06-07 23:58:41
GC在需要的时候运行。一般来说,(甚至在DVM上)它真的比你更清楚什么时候需要运行。如果你认为这个问题不是GC的问题,而是你的应用程序内存的问题,它可能会帮助你找到解决方案。
频繁发生GC的最可能的原因是您的内存几乎不足。例如,如果您分配了大量短期对象,则可能会发生这种情况:您分配它们的速度很快,但忘记它们的速度也同样快。每次GC运行时,它都会成功地恢复足够的内存供应用程序继续运行……但同样快的是,你又一次填满了内存。
如果这确实是正在发生的事情,那么,如果你有更多的内存,就像@parry建议的那样,你只需要延迟问题。GCs发生的频率会更低,但运行时间会更长(因为它们会收集更多的垃圾)。这可能足够了,但可能还不够。
检查是否在频繁调用的例程(例如,绘图例程)中分配对象。
发布于 2013-11-04 06:40:42
如果您认为GC的行为很愚蠢(很有可能),并且VM有更多的空闲内存,那么您可以尝试通过请求1/5/10MB的分配(使用try-catch for OOME来保护它)来强制它增加堆大小。这可能会导致GC在每个周期中清理更多,或者增加发生完整GC的机会。
另一个在PC上有效的启发式方法是在一个循环中调用System.GC() x次,以触发完整的GC。
总而言之,我自己也遇到了它,它很糟糕。
https://stackoverflow.com/questions/16985765
复制相似问题