【JVM内存管理专题】——Java参数调优

JVM参数调优——日志开启

-XX:+PrintGC 每次触发GC的时候打印相关日志
-XX:+PrintGCDetails 更详细的GC日志

JVM参数调优——总体限制

-Xms 20m 堆初始值
-Xmx 5m 堆最大可用值
-Xmn 10m 新生代堆最大可用值
-Xss 5m 栈最大调用深度
Ps:在实际工作中,我们可以直接将初始的堆大小与最大堆大小相等,这样的好处是可以减少程序运行时垃圾回收次数,从而提高效率。

JVM参数调优——总体限制

-XX:SurvivorRatio=2 用来设置新生代中eden空间和from/to空间的比例.
-XX:NewRatio=1/2 配置新生代与老年代占比 1:2
-XX:SurvivorRatio8
-XX:PretenureSizeThreshold 直接进入老年大的内存大小(避免大对象在Eden区及两个Survivor区之间发生大量的内存复制,只对Serial和ParNew两款收集器有效)
-XX:MaxTenuringThreshold 进入老年代的年龄(Survivor某个年龄占据内存总和大于Survivor空间的一半,大于该年龄的直接进入内存)
HandlePromotionFailure 是否允许担保,不允许则直接full GC,否则判断后FullGc
【零栖息方案】
我们知道ParNew收集器使用的是复制算法,这个算法的高效是建立在大部 分对象都“朝生夕灭”
的特性上的,如果存活对象过多还搞FROM/TO,把这些对象复制到Survivor并维持这 些对象引用的正确就成为一个沉重的负担,因此导致GC暂停时间明显变长;
可以考虑将Survivor空间去掉 (加入参数
-XX:SurvivorRatio=65536、
-XX:MaxTenuringThreshold=0或者
-XX: +AlwaysTenure),让新生代中存活的对象在第一次Minor GC后立即进入老年代

JVM参数调优——常见回收

【Direct Memory回收机制】
Direct Memory却不能 像新生代、老年代那样,发现空间不足了就通知收集器进行垃圾回收,它只能等待老年代满 了后Full GC。否则它只能一直等到抛出内存溢出 异常时,先catch掉,再在catch块里面“大喊”一声:“System.gc()!
-XX:MaxDirectMemorySize调整大小,内存不足时抛出 OutOfMemoryError或者OutOfMemoryError:Direct buffer memory。
每个Socket连接都Receive和Send两个缓存区,分别占大约37KB和25KB内
存,连接多的话这块内存占用也比较可观。如果无法分配,则可能会抛出IOException:Toomany open files异常。
【MinorGc-新生代回收机制】
因为 Java 对象大多都具备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
【MijorGc-老年代回收机制】
当发生不足够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间MajorGC 会产生内存碎片,为了减少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配;
老年代 GC(Major GC / Full GC):指发生在老年代的 GC,出现了 Major GC,经常会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度一般会比 Minor GC 慢 10倍以上。
【FullGc】
老年代担保空间失败(没足够空间容纳新的晋升);永久代超过临界值
Ps:默认为申请4个G的堆内存!单位默认是字节,byte数据类型每个占用1个字节;
【永久代回收】
废弃常量:常量不可达
无用的类:
该类所有的实例都已经被回收
加载该类的ClassLoader已经被回收
该类对应的java.lang.Class对象没有在任何地方被引用
Ps:在大量使用反射、动态代理、CGLib等ByteCode框架、动态生成JSP以及OSGi这类频繁 自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出

JVM参数调优——IDE数据打印

byte[]a=new byte[4*1024*1024];
System.out.println("堆最大内存"+Runtime.getRuntime().maxMemory()/1024/1024+"M");
System.out.println("堆空闲内存"+Runtime.getRuntime().freeMemory()/1024/1024+"M");
System.out.println("堆已用内存"+Runtime.getRuntime().totalMemory()/1024/1024+"M");

GodSchool
致力于简洁的知识工程,输出高质量的知识产出,我们一起努力
博主私人微信:supperlzf

你可能感兴趣的:(JVM内存管理专题,jvm,java)