架构师的成长必经之路

说到jvm调优,实质上就是对java内存的合理使用,进而减少full gc的频率和时间,提高应用的运行效率。下面就从内存结构,内存分配与回收和垃圾收集器这三个方面来进行说明。

1:jvm的内存结构

架构师的成长必经之路 jvm调优

jvm内存结构

方法区和堆是线程共享的。java栈,本地方法栈和程序计数器是每个线程私有的。调优的主要对象就是方法区和堆栈。

1)方法区 :所有定义的方法的信息都保存在该区域,静态变量+常量+类信息(构造方法/接口定义)+运行时常量池都存在方法区中。(java8里彻底被移除,取而代之的是元数据区)

2)堆简单来说就是虚拟机启动时创建,用于存放对象实例的地方,几乎所有的对象(包含常量池)都在堆上分配内存。

架构师的成长必经之路 jvm调优

堆结构

年轻代(Young Generation):分为伊甸区(Eden space)和幸存者区(Survivor pace)。当伊甸园的空间用完时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。然后将伊甸园中的剩余对象移动到幸存 0区。若幸存 0区也满了,再对该区进行垃圾回收,然后移动到1区。然后来回15次(可以设置)后,就会进入老年代。当然,如果幸存区不够大的情况,会直接进入年老代。

老年代(Old Generation):新生区经过多次GC仍然存活的对象移动到老年区。若老年区也满了,那么这个时候将产生MajorGC(FullGC),进行老年区的内存清理。若老年区执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”。

2:JVM内存分配与回收

新生代GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC非常频繁,回收速度一般也比较快。

老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC的慢10倍以上。

实际运用过程中,可以通过-XX:+PrintGCDetails 来打印垃圾回收的整个过程。

架构师的成长必经之路 jvm调优

虚拟机判断是否可以垃圾回收的算法是可达性算法,大概的意思就是从Gc roots(类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等等)根节点对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。

判断一个类是否可以回收的三个标准:

1)该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。

2)加载该类的 ClassLoader 已经被回收。

3)该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法

虚拟机可以对满足上述3个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收。

3:垃圾回收器

常用的垃圾回收器主要有,

1)Serial(串行)收集器(-XX:+UseSerialGC)

这个模式对占有内存较少的应用很管用,用在新生代,可以和CMS配合使用。

2)ParNew(并发)收集器 (-XX:+UseParallelGC)

是多线程版的串行收集器。用在新生代,可以和CMS配合使用。

2)CMS收集器(-XX:+UseConcMarkSweepGC)

CMS收集器也被称为短暂停顿并发收集器。它是对年老代进行垃圾收集的。CMS收集器通过多线程并发进行垃圾回收,尽量减少垃圾收集造成的停顿。因为垃圾回收的方法不同,所以比并发收集器的停顿时间更短,但是会和cpu抢占资源,还会产生大量碎片。

4)G1收集器(-XX:+UseG1GC)

G1收集器和其他的收集器运行方式不一样,不区分年轻代和年老代空间。主要针对配备多颗处理器及大容量内存的机器. G1将Java堆划分为多个大小相等的独立区域(Region),虽保留新生代和老年代的概念,但不再是物理隔阂了,它们都是(可以不连续)Region的集合。

分配大对象(直接进Humongous区,专门存放短期巨型对象,不用直接进老年代,避免Full GC的大量开销)不会因为无法找到连续空间而提前触发下一次GC。

lG1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内完成垃圾收集。

架构师的成长必经之路 jvm调优

垃圾回收器没有最好的,各有特点,要根据自己的业务场景选择合适的垃圾回收器。以下是给出的几点建议;

1. 如果内存小于100M,使用串行收集器

2. 如果是单核,并且没有停顿时间的要求,串行或JVM自己选择

3. 如果允许停顿时间超过1秒,选择并行或者JVM自己选

4.如果响应时间最重要,并且不能超过1秒,使用并发收集器,CMS和G1.

最后从实战的角度,谈一些经验,供大家参考

第一步:确定调优的两个指标:停顿时间(垃圾收集器做垃圾回收中断应用执行的时间)和吞吐量(花在垃圾回收的时间和应用时间的占比)。吞吐量一般在90%以上就可以了。

第二步:打印GC日志(-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:./gc.log)

第三步:分析GC原因,调整jvm参数。主要的几个参数就是,堆栈参数,垃圾收集器以及对应垃圾收集器的各个参数。(在没懂各个参数的含义之前建议不要在生产上调整)。可视化分析工具有gceasy,GCViewer.

附录:GC常用参数

堆栈设置

-Xss:每个线程的栈大小

-Xms:初始堆大小,默认物理内存的1/64

-Xmx:最大堆大小,默认物理内存的1/4

-Xmn:新生代大小

-XX:NewSize:设置新生代初始大小

-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。

-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。

-XX:MetaspaceSize:设置元空间大小

-XX:MaxMetaspaceSize:设置元空间最大允许大小,默认不受限制,JVM Metaspace会进行动态扩展。

垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

收集器设置

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器

-XX:+UseParallelOldGC:年轻代和老年代都使用并行回收收集器

-XX:+UseParNewGC:在新生代使用并行收集器

-XX:+UseParalledlOldGC:设置并行老年代收集器

-XX:+UseConcMarkSweepGC:设置CMS并发收集器

-XX:+UseG1GC:设置G1收集器

-XX:ParallelGCThreads:设置用于垃圾回收的线程数

并行收集器设置

-XX:ParallelGCThreads:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis:设置并行收集最大暂停时间

-XX:GCTimeRatio:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

CMS收集器设置

-XX:+UseConcMarkSweepGC:设置CMS并发收集器

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads:设置并发收集器新生代收集方式为并行收集时,使用的CPU数。并行收集线程数。


-XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩

-XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收


-XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况

-XX:ParallelCMSThreads:设定CMS的线程数量


-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发

-XX:+
UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理

G1收集器设置

-XX:+UseG1GC:使用G1收集器

-XX:ParallelGCThreads:指定GC工作的线程数量

-XX:G1HeapRegionSize:指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区

-XX:GCTimeRatio:吞吐量大小,0-100的整数(默认9),值为n则系统将花费不超过1/(1+n)的时间用于垃圾收集

-XX:MaxGCPauseMillis:目标暂停时间(默认200ms)

-XX:G1NewSizePercent:新生代内存初始空间(默认整堆5%)

-XX:G1MaxNewSizePercent:新生代内存最大空间


-XX:TargetSurvivorRatio:Survivor填充容量(默认50%)

-XX:MaxTenuringThreshold:最大任期阈值(默认15)


-XX:InitiatingHeapOccupancyPercen:老年代占用空间超过整堆比IHOP阈值(默认45%),超过则执行混合收集

-XX:G1HeapWastePercent:堆废物百分比(默认5%)

-XX:G1MixedGCCountTarget:参数混合周期的最大总次数(默认8)                                                        希望对你有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值