我有一个应用程序,基本上,创建一个新的字节数组(小于 1K)在几秒钟后存储一些数据(通常少于 1 分钟,但一些数据存储长达 1 小时)写入磁盘,数据将进入垃圾。每秒创建大约 400 个数据包。我读过一些文章说不用担心 GC,尤其是快速创建和释放的内存部分(在 Java 6 上)。GC 运行时间过长导致我的应用程序出现一些问题。我设置了一些 GC 参数(更大的 XMX 和 ParalelGC),这减少了 Full GC 时间减少但还不够。我有两个想法,我是关注 GC 参数还是创建字节数组内存池机制?哪一个更好?
问问题
368 次
3 回答
4
执行 GC 的频率取决于对象的大小,但成本(清理时间)更多地取决于对象的数量。我怀疑长期存在的数组正在空间之间被复制,直到它最终进入旧空间并最终被丢弃。清洁老一代相对昂贵。
我建议你尝试使用 ByteBuffer 来存储数据。它们与 byte[] 类似,但大小可变,如果您可以将直接字节缓冲区与 NIO 一起使用,则效率会稍高一些。预分配缓冲区可以更有效地预分配缓冲区。(虽然会浪费虚拟内存)
顺便说一句:直接字节缓冲区使用很少的堆空间,因为它们使用“C”空间中的内存。
于 2011-01-17T12:46:40.163 回答
0
我建议你分析一下为什么 GC 对你来说不够好。您可以使用jmap
转储堆,然后使用jhat
Eclipse Memory Analyzer来查看其中存在哪些对象。您可能会发现自己持有不再需要的参考资料。
GC 非常聪明,您实际上可以通过使用自己的内存管理代码来超越它,从而使事情变得更糟。尝试调整参数,也许您也可以尝试新的 G1 垃圾收集器。
另外,请记住,GC 喜欢短暂的、不可变的对象。
于 2011-01-17T12:59:26.303 回答
0
- 使用分析器识别代码片段
- 尝试使用弱引用。
- 向 VM 建议 GC 算法
-Xgc: parallel
- 设置一个大堆和共享内存
-XX:+UseISM -XX:+AggressiveHeap
- 下面设置垃圾收集。
-XX:SurvivorRatio 8
于 2011-01-17T13:07:08.723 回答