如何提高 Java 应用程序内存的效率?

2022-09-02 05:15:27

如何优化具有大量(数百万)长期存在对象的应用程序的堆大小使用情况?(大缓存,从数据库加载大量记录)

  • 使用正确的数据类型
    • 避免使用 java.lang.String 来表示其他数据类型
  • 避免重复的对象
    • 如果事先知道值,请使用枚举
    • 使用对象池
    • String.intern() (好主意?)
  • 仅加载/保留您需要的对象

我正在寻找一般编程或Java特定的答案。没有时髦的编译器开关。

编辑:

优化可在堆中出现数百万次的 POJO 的内存表示形式。

使用案例

  • 在内存中加载一个巨大的csv文件(转换为POJO)
  • 使用休眠从数据库中检索数百万条记录

答案的恢复:

  • 使用蝇量级图案
  • 写入时复制
  • 与其加载具有 3 个属性的 10M 对象,不如使用 3 个大小为 10M 的数组(或其他数据结构)更有效?(操作数据可能很痛苦,但如果你真的内存不足......)

答案 1

我建议您使用内存分析器,查看内存消耗的位置并进行优化。如果没有定量信息,你最终可能会改变一些没有影响或实际上使事情变得更糟的事情。

您可以考虑更改数据的表示形式,尤其是在对象较小时。例如,可以将数据表表示为一系列列,每列都有对象数组,而不是每行一个对象。如果不需要表示单个行,这可以为每个对象节省大量开销。例如,具有12列和10,000,000行的表可以使用12个对象(每列一个),而不是1000万个(每行一个)


答案 2

你没有说你想要存储什么样的物品,所以提供详细的建议有点困难。但是,一些(非排他性)方法,没有特定的顺序,是:

  • 尽可能使用蝇量级图案
  • 缓存到光盘。有许多针对 Java 的缓存解决方案
  • 关于String.intern是否是一个好主意,存在一些争论。有关问题,请参阅此处。String.intern(),以及围绕其适用性的争论程度。
  • 利用引用或引用来存储可以按需重新创建/重新加载的数据。有关如何将软引用与缓存技术结合使用,请参阅此处

详细了解要存储的对象的内部和生存期将得到更详细的答案。