标签:
了解jvm内存管理看这里:jvm是如何管理内存的
了解堆内存看这里:java堆内存是什么样的
java内存的优化主要是通过合理的控制GC来实现,主要原则:
1. 不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况(因为GC过后这个值是不会变化的)。
2. 使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。
3. 优化内存主要的目的是降低youngGC的频率、减少fullGC的次数 ,过多的youngGC和fullGC是会占用很多的系统资源(主要是CPU),影响系统的吞吐量。
这里,影响内存效率最关键的就是:fullGC,因为它会对整个堆内存进行整理,占用大量的资源。
fullGC作为java内存管理的关键,它的触发时机我们一定要掌握,有4种情况会发生fullGC:
旧生代空间不足
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象。
Pemanet Generation空间不足
增大Perm Gen空间,避免太多静态对象。了解内存溢出看这里:java什么情况会内存溢出
GC后晋升到老生代的平均大小大于老生代剩余空间
控制好新生代和旧生代的比例。
System.gc()被显示调用
垃圾回收不要手动触发,尽量依靠JVM自身的机制。
GC调优手段主要是通过控制堆内存的各个部分比例,以及根据不同场景采用不同的GC策略来实现。下面分别来看:
通过控制堆内存比例优化GC
新生代设置过大
一是新生代设置过大会导致旧生代过小(堆总量一定),从而诱发fullGC。
二是新生代GC耗时大幅度增加。
一般说来新生代占整个堆1/3比较合适。
Survivor设置过小
新生代中根据优化复制算法,如果Survivor区(S0,S1)太小,会导致对象从eden区直接到达旧生代,降低了在新生代的存活时间。一般来说Eden:S0:S1为8:1:1是比较合理的。
了解新生代复制算法看这里:什么是新生代的复制算法
Survivor设置过大
若Survivor区过大,则eden区会过小,eden区容易达到阈值导致新生代GC频率增加。
新生代对象存活时间过短
通过-XX:MaxTenuringThreshold=n来控制新生代存活时间,如果存活时间过短,则对象会很快进入老生代,导致fullGC。所以要尽量让不常用对象在新生代被回收。
通过GC策略优化GC
新生代和旧生代都有很多种GC策略和组合搭配,选择这些策略对于我们这些开发人员是个难题,默认情况下JVM会自动调整新生代与老生代的比例、Eden区与Suvivor区的比例来达到性能目标,JVM提供两种较为简单的GC策略的设置方式:
吞吐量优先
JVM以吞吐量为指标,自行选择相应的GC策略及 控制堆内存的大小比例,来达到吞吐量指标。一次fullGC时间占总可用时间的比例,如果GC时间过长,会相应调整空间的大小(花费在GC上的时间比例不超过1 / (1 + n))。
通过-XX:GCTimeRatio=n来设置。
暂停时间优先
JVM以暂停时间为指标,自行选择相应的GC策略及控制堆内存的大小比例,尽量保证每次GC造成的应用停止时间都在指定的数值范围内完成。如果时间过长,会相应调整空间的大小(单位是毫秒)。
通过-XX:MaxGCPauseMillis=n来设置。
Java千百问_07JVM架构(016)_java内存如何优化
标签:
原文地址:http://blog.csdn.net/ooppookid/article/details/51582772