【发布时间】:2014-12-21 08:22:52
【问题描述】:
对于应用程序,我正在努力提高效率非常重要。为了避免不必要的垃圾收集,我分配了很多内存(为了增加堆大小)并立即释放它。但是,无论我有多少可用内存,垃圾收集仍然会发生。
当我不进行这种额外的内存分配/释放时,我只有 24% 的可用内存,而下面的日志中为 63%,但 GC 调用的数量是相同的。 GC 暂停是相同的。执行时间(程序)是相同的。
谁能解释一下这种奇怪的 GC 行为?为什么GC_FOR_ALLOC 会被触发?有大量可用内存。
在我的程序中主要的操作是:文件读取、加密、数据传输。
对于数据传输和文件读取,我使用ByteBuffer和FileChannel,SocketChannel。
大量的 ByteBuffer 分配会成为瓶颈吗?
好像我也没有任何内存泄漏。
在 GalaxyS3 (Android 4.4.2) 和 GalaxyS2 (Android 4.1.2) 上测试的程序
12-21 00:30:54.973: I/dalvikvm-heap(30222): Grow heap (frag case) to 44.361MB for 25000016-byte allocation
12-21 00:30:55.463: D/dalvikvm(30222): GC_FOR_ALLOC freed 43K, 8% free 42893K/46416K, paused 20ms, total 20ms
12-21 00:31:01.900: D/dalvikvm(30222): GC_FOR_ALLOC freed 28367K, 63% free 18615K/49480K, paused 39ms, total 39ms
12-21 00:31:07.606: D/dalvikvm(30222): GC_FOR_ALLOC freed 3600K, 63% free 18648K/49480K, paused 42ms, total 42ms
12-21 00:31:12.151: D/dalvikvm(30222): GC_FOR_ALLOC freed 3640K, 63% free 18652K/49480K, paused 48ms, total 48ms
12-21 00:31:17.757: D/dalvikvm(30222): GC_FOR_ALLOC freed 3627K, 63% free 18669K/49480K, paused 93ms, total 93ms
12-21 00:31:24.014: D/dalvikvm(30222): GC_FOR_ALLOC freed 3641K, 63% free 18679K/49480K, paused 46ms, total 46ms
12-21 00:31:30.090: D/dalvikvm(30222): GC_FOR_ALLOC freed 3644K, 63% free 18688K/49480K, paused 48ms, total 48ms
12-21 00:31:35.536: D/dalvikvm(30222): GC_FOR_ALLOC freed 3639K, 63% free 18706K/49480K, paused 50ms, total 50ms
12-21 00:31:41.763: D/dalvikvm(30222): GC_FOR_ALLOC freed 3659K, 63% free 18711K/49480K, paused 52ms, total 53ms
12-21 00:31:47.439: D/dalvikvm(30222): GC_FOR_ALLOC freed 3652K, 63% free 18724K/49480K, paused 54ms, total 54ms
12-21 00:31:53.085: D/dalvikvm(30222): GC_FOR_ALLOC freed 3677K, 63% free 18716K/49480K, paused 38ms, total 38ms
12-21 00:31:59.882: D/dalvikvm(30222): GC_FOR_ALLOC freed 3672K, 63% free 18711K/49480K, paused 50ms, total 67ms
12-21 00:32:05.838: D/dalvikvm(30222): GC_FOR_ALLOC freed 3672K, 63% free 18704K/49480K, paused 42ms, total 42ms
12-21 00:32:13.276: D/dalvikvm(30222): GC_FOR_ALLOC freed 3680K, 63% free 18686K/49480K, paused 37ms, total 37ms
附:代码很长,不能发。
感谢您的帮助、提示或猜测。
【问题讨论】:
-
这里奇怪的不是垃圾收集;这是您的应用程序的行为
-
@AndrewBarber 应用程序的行为有什么问题?为什么不是GC?
-
你的第一段。这不是应用程序通常的行为方式。您似乎也不了解垃圾收集的工作原理或原因。可用内存并不像您想象的那么重要。
-
@AndrewBarber。但是有了这个空闲内存量,应该触发 GC_CONCURRENT。它应该比 GC_FOR_ALLOC 更快。
-
重读后-分配和释放内存是造成这种情况的原因。最好的办法是在对象级别分配和重用。顺便说一下,分配一大块内存然后释放它会增加应用程序的堆,但不是很好。在 GC 运行之前,分配的内存仍将被分配。所以新声明的内存实际上不能被重用。这意味着您的算法将请求更多内存来获得可用内存。如果您实际上没有请求足够的空间来增长堆,那么这尤其糟糕,但实际上它是从预先分配的内存中填充的
标签: android memory-management garbage-collection