是否值得减轻垃圾收集的影响?

izb*_*izb 11 java caching garbage-collection memory-management java-me

我有一个应用程序,内存配置文件看起来像这样:

Jaggy http://kupio.com/image-dump/spikeymem.png

内存使用的缓慢向上爬行是由批次和大量小而简单的瞬态对象的分配引起的.在内存不足的情况下(这是一个移动应用程序),与较少限制的内存量相比,GC开销很明显.

因为我们知道,由于应用程序的性质,这些尖峰将继续存在,我正在考虑某种众多的瞬态对象池(真棒名称).这些对象将在应用程序的生命周期中存在,并在可能的情况下重复使用(对象的生命周期很短且可预测性很强).

希望这可以减少收集的对象数量并提高性能,从而减轻GC的影响.

显然,这也有其自身的性能限制,因为"分配"会更昂贵,并且维护缓存本身会有开销.

由于这将是对大量代码的相当大的侵入性更改,我想知道是否有人尝试了类似的东西,如果它是一个好处,或者在这种情况下是否有任何其他已知的减轻GC的方法.有关管理可重用对象缓存的有效方法的想法也是受欢迎的.

oxb*_*kes 6

这类似于GoF模式书中详述的flyweight模式(参见下面的编辑).由于在减少对象创建,同步和GC开销方面取得了进展,对象池在"普通"虚拟机中已经失宠.然而,这些肯定已经存在很长时间了,尝试它们看看它们是否有帮助当然很好!

当然,与上面提到的池化开销(数据库连接是一个明显的例子)相比,对象池仍然用于具有非常昂贵的创建开销的对象.

只有一个测试会告诉您池化方法是否适用于您的目标平台!

编辑 - 我把OP "尽可能重用"意味着对象是不可变的.当然,情况可能并非如此,flyweight模式实际上是关于共享的不可变对象(Enums是flyweight的一个例子).可变(read:unshareable)对象不是flyweight模式的候选对象,但是(当然)对象池.

  • 我觉得答案中有点暗示.如果GoF写了一本书,将其作为一种常见模式,那么它就是这个问题的潜在解决方案 (2认同)

ska*_*man 2

通常,我会说这是一项调整虚拟机 GC 参数的工作,以减少尖峰,但对于移动应用程序来说,这并不是一个真正的选择。因此,如果您使用的 JVM 无法修改其 GC 行为,那么老式对象池可能是最好的解决方案。

Apache Commons Pool 库对此很有用,但如果这是一个移动应用程序,那么您可能不希望库依赖项开销。