您如何提高Java应用程序内存?
-
16-09-2019 - |
题
您如何优化具有大量(数百万)长寿命对象的应用程序的堆尺寸使用情况? (大型缓存,从数据库中加载大量记录)
- 使用正确的数据类型
- 避免Java.lang.String表示其他数据类型
- 避免重复的对象
- 如果预先知道这些值,请使用枚举
- 使用对象池
- string.intern()(好主意?)
- 加载/仅保留您需要的对象
我正在寻找一般编程或Java特定答案。没有时髦的编译器开关。
编辑:
优化可以在堆中出现数百万次的POJO的内存表示。
用例
- 在内存中加载巨大的CSV文件(转换为Pojos)
- 使用Hibernate从数据库中检索数百万个记录
答案简历:
- 使用轻量级图案
- 复制写
- 与其加载3个属性的10m对象,不如将3个数组(或其他数据结构)的大小为10m更有效? (可能是操纵数据的痛苦,但是如果您真的缺乏记忆...)
其他提示
我建议您使用内存剖面,查看内存的消耗何方并优化。如果没有定量信息,您最终可能会改变任何没有效果或实际上使情况变得更糟的事情。
您可以查看更改数据的表示形式,ESP如果您的对象很小。例如,您可以将数据表表示为一系列列,每个列的对象数组,而不是每行一个对象。如果您不需要表示单个行,则可以为每个对象节省大量的开销。例如,一张具有12列和10,000,000行的表可以使用12个对象(每列1个),而不是1000万(每行1个)
确保对象模型的良好正常化,不要重复值。
哎呀,如果只有数百万个物体,我认为我只需要去一个不错的64位VM和很多RAM;)
普通的“剖道师”对您没有太大帮助,因为您需要对所有“实时”对象的概述。您需要堆转储分析仪。我推荐 Eclipse内存分析仪.
从字符串开始检查是否重复的对象。检查您是否可以应用诸如Flighteweight,CopyOnwrite,Lazy初始化(Google将是您的朋友)等模式。
看一下从这里链接的此演示文稿。它列出了通用Java对象和原语的内存使用,并帮助您了解所有额外的内存去向。
You could just store fewer objects in memory. :) Use a cache that spills to disk or use Terracotta to cluster your heap (which is virtual) allowing unused parts to be flushed out of memory and transparently faulted back in.
I want to add something to the point Peter alredy made(can't comment on his answer :() it's always better to use a memory profiler(check java memory profiler) than to go by intution.80% of time it's routine that we ignore has some problem in it.also collection classes are more prone to memory leaks.
If you have millions of Integers and Floats etc. then see if your algorithms allow for representing the data in arrays of primitives. That means fewer references and lower CPU cost of each garbage collection.
A fancy one: keep most data compressed in ram. Only expand the current working set. If your data has good locality that can work nicely.
Use better data structures. The standard collections in java are rather memory intensive.
[what is a better data structure]
- If you take a look at the source for the collections, you'll see that if you restrict yourself in how you access the collection, you can save space per element.
- The way the collection handle growing is no good for large collections. Too much copying. For large collections, you need some block-based algorithm, like btree.
Spend some time getting acquainted with and tuning the VM command line options, especially those concerning garbage collection. While this won't change the memory used by your objects, it can have a big impact on performance with memory-intensive apps on machines with a lot of RAM.
Assign null
value to all thevariables
which areno longer
used. Thusmake it available for Garbage collection
.De-reference the collections
once usage is over, otherwise GC won't sweep those.