JVM调优
参考博客深入了解JVM的底层原理
GC垃圾收集方法
- 标记清除 mark-sweep
产生碎片 - 复制 copying
不产生碎片 ,多使用一半的内存空间 - 标记整理(标记-清理-整理) mark-compact
在标记清理上对对象进行移动,成本更高
对象引用强度
- 强引用
new Object() 只有引用没有了才能被GC - 软引用
内存满后GC ,不管引用是否存在被GC - 弱引用
只存在于下一次GC之前 - 虚引用
设置虚引用的作用GC后收到系统通知
内存调优
- 原因: 过多的GC和Full GC会占用大量的资源(主要是CPU)影响系统的吞吐量
- 目的:减少GC次数 减少GC频率 尽量降低GC 所导致的应用线程暂停时间
- 手段: 主要针对内存管理的调优,包括控制各个代的大小,GC策略
内存控制
- 导致FULL GC的原因
- 老年代空间不足
- GC晋升至老年代的平均大小大于剩余老年代剩余空间
- 控制内存中各个部分的比列
- 新生代设置过小
- 导致频繁的新生代gc
- 导致大对象直接进入老年代,占据大量老年代空间,导致fullGC
- 新生代设置过大
- 内存一定情况下,新生代过大导致老年代变小,诱发fullGC
- 新生代内存过大 GC耗时大幅度增加
- 新生代设置过小
GC策略
- 吞吐量优先
JVM以吞吐量为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,来达到吞吐量指标。这个值可由-XX:GCTimeRatio=n - 暂停时间优先
JVM以暂停时间为指标,自行选择相应的GC策略及控制新生代与旧生代的大小比例,尽量保证每次GC造成的应用停止时间都在指定的数值范围内完成。这个值可由-XX:MaxGCPauseRatio=n来设置
- 小知识
- GCTimeRatio
- MaxGCPauseRatio
JVM常见配置
1、堆设置
-Xms:初始堆大小
-Xmx:最大堆大小
-XX:NewSize=n:设置年轻代大小
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1: 3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区 有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n:设置持久代大小
2、收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
3、垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
4、并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
5、并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU 数。并行收集线程数。
注意:在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。
ClassLoader的加载原理
双亲委派模型
java提供的三层classloader
- Bootstrap classLoader:主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。
- ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。
- AppClassLoader:主要负责加载应用程序的主函数类
作用
- 防止顶级类被修改
- 防止重复加载