java gc日志设置参数_47 jvm性能优化之GC日志参数分析

回收算法

标记清除算法

根据gcRoot对象的引用链,发现如果该对象没有被引用的情况下,

则标记为垃圾,在清除。

优点:算法简单

缺点:容易产生内存碎片

标记整理算法

根据gcRoot对象的引用链,发现如果该对象没有被引用的情况下,

则标记为垃圾

标记整理与标记清除区别在于:避免标记清除算法产生的碎片问题,

清除垃圾过程中,会将可用的对象实现移动,内存空间更加具有连续性。

优点:没有内存的碎片问题

缺点:整理过程中会产生内存地址移动,效率可能偏低。

标记复制算法

根据gcRoot对象的引用链,发现如果该对象没有被引用的情况下,

将正在被引用的对象拷贝到to区中,让后再直接清理整个from区,在交换位置。

优点:不会产生内存碎片

缺点:比较占内存空间

分代算法

9f13fd26a9f5

image.png

分代算法中主要分成三代: 新生代/from或者 to/老年代

默认 新生代(Young)与老年代(Old)的比例的值为 1:2 (该值可以通过参数–XX:NewRatio 来指定)。

默认的 Eden:from:to=8:1:1 (可以通过参数 –XX:SurvivorRatio 来设定)。

新生代:刚创建的对象都存放在新生代中eden区,当eden区空间内存满之后,则根据GC可达分析算法,将幸存的对象拷贝到to区中,并且寿命+1. 如果该对象的寿命>15的情况下

则将该对象放入到老年代中。

老年代:Minor GC新生代GC ,回收多次如果该对象还一直被引用的情况下,则放入到老年代中,如果新生代和老年代内存都满的情况下,则会触发FullGC

总结:

1.对象首先分配到eden区(伊田园区) 新生代GC (Minor GC)

2.新生代空间不足时,触发Minor GC,将eden区(伊田园区)存活的对象采用标记复制算法放入到to区中,并且该对象的寿命+1

注意:Minor GC因为标记复制算法,会触发stop the world 暂停其他用户的线程,等待垃圾回收结束之后,其他的用户线程才会继续执行。

3.如果该对象的寿命>15的情况下,则将该对象放入到老年代中,对象寿命放入在对象头中。

4.当老年代空间不足的时候,会触发FullGC 采用标记清理/整理算法

5.新生代GC非常频繁,速度比老年代GC要高。

GC相关参数

Stop-The-World

在垃圾回收过程中经常涉及到对对象的挪动(比如上文提到的对象在Survivor 0和Survivor 1之间的复制),进而导致需要对对象引用进行更新。为了保证引用更新的正确性,Java将暂停所有其他的线程,这种情况被称为“Stop-The-World”,导致系统全局停顿。Stop-The-World对系统性能存在影响,因此垃圾回收的一个原则是尽量减少“Stop-The-World”的时间。

回收算法:

误区:没有引用计数算法

1.标记清除算法

2.标记整理算法

3.标记复制算法

回收算法是针对不同的场景使用

按照分代使用

新生代:标记复制算法

老年代:标记清除/标记整理

为什么新生代使用 标记复制算法?而老年代使用标记清除/标记整理

为什么新生代使用 标记复制算法?而老年代使用标记清除/标记整理

因为新生代gc非常频繁,所以选择效率比较高的垃圾回收算法。、

标记清除算法:

优点:算法非常简单。

缺点:空间地址不连续

为什么标记清除算法:空间地址不连续 没有整理

标记整理算法:

优点:空间地址保持连续

缺点:速度慢、会产生移动内存地址 在移动过程中其他线程无法访问堆内存。

标记复制算法:

优点:空间地址保持连续、效率比标记整理算法要高。

缺点: 存在两个空间,占用空间。

分为两个区域:from 和to区 相等。

From和to切换

原理:

当我们堆内存触发gc的时候,在from区中将可用对象拷贝到to中,在直接将整个from

区清空,依次循环切换。

垃圾收集器 并行、串行、cms g1

分代算法:

首先,对我们堆内存空间实现分代,核心分为新生代、老年代

新生代:刚创建的对象一般的情况下都是放在新生代中

分为:eden区() from区 to区

刚创建的对象会放在eden区,当我们新生代eden区空间满的

情况下,会将引用的对象拷贝到to区中,如果gc回收15次的时候

发现该对象还一直被使用的情况下,该对象就会晋升为老年代中。

老生代:

存储空间比例:

1.默认的情况下新生代与老年代存储空间比例是1:2

2.新生代中eden区与from/to区

为什么新生代中from/to区 比例是1:1

因为新生代中使用的标记复制算法

老年代在什么的情况下会发生fullgc

1.在新生代和老年代有堆内存空间都快满的时候。

新生代GCMinorGC

老年代fullgc

当我们老年代gc开始回收垃圾的时候,也会触发新生代gc回收。

老年代在什么时候触发:

当我们老年代空间装不下的时候。

依次内推如何演示新生代gc

Java垃圾收集算法 cms、g1收集器

1.标记清除、标记整理、标记复制算法(引用计数法)

1.标记清除算法:

优点:算法实现简单

缺点: 内存空间不连续、空间利用率不高 容易产生碎片化

2.标记整理算法

优点:空间具有连续性 没有产生碎片化的问题 效率比较低

缺点:对象的应用内存地址有可能会发生变化

3.标记复制算法

优点:效率比较高,保证空间连续性的问题

缺点:以空间的方式换时间

分代算法:

分为新生代和老年代

新生代:刚创建的对象都存放到新生代中 ,在新生代中有分成三个区域。

新生代中分为 eden区、from和to区

刚创建的对象存放到eden区,当eden区如果满的时候,幸存的对象晋升为存放到

From或者是to区

新生代触发的GCMinorGC

老年代触发的GCFullGC

那些对象会晋升到老年代中?

1.年限达到当gc多次在回收的时候,如果能够一直引用到一个阈值的情况下。直接晋升到老年代中。

2.直接是大对象

在默认的情况下 新生代与老年代存储空间比例 是为1:2

在默认的情况下,新生代中 eden区域与from或者是to占比是为8:1:1

程序发生内存溢出:存放的对象空间大小大于我们老年代的空间大小。

因为在整合堆内存中,新生代触发gc回收次数一定比老年代多。

为什么在分代算法中 新生代中有from和to区大小一样。

因为新生代中gc触发非常频繁,为了能够更加高效清理垃圾,所以采用标记复制算法。

垃圾收集器在什么开始触发收集垃圾?

当新生代或者是老年代内存满的情况下,开始触发垃圾

垃圾收集器之前频繁推出垃圾收集器

Stop-The-World 问题

Stop-The-World:当我们垃圾收集器在回收垃圾的时候,

当垃圾回收线程在清理垃圾的时候,会暂停我们的所以用户线程。

导致当前的用户线程短暂卡

在生产环境中调优jvm: 不要频繁触发垃圾回收或者是降低用户线程阻塞的时间

所有的收集器:在回收垃圾的时候都会暂停我们用户的线程

怎样避免触发垃圾收集器频繁回收?

1.堆内存空间设置比较大

2.堆内存初始化 与最大值一定保持一致。

3.生产环境中不要去调用System.gc();

垃圾收集器 与垃圾收集算法区别:

垃圾收集器:串行、并行收集、CMS、G1 Java11 ZGC收集器,能够降低对我们用户线程暂停的时间或者用户线程和GC线程同时运行

垃圾收集算法:回收算法:标记清除、标记整理、标记复制、分代算法

Stop-The-World

当我们在触发gc回收的时候,有可能会暂停用户的线程。

JVM参数

如果存放的对象空间大于新生代空间,该对象会直接放到老年代中。

GC核心参数

-Xms100 -Xmx

1、-Xms

初始大小内存,默认为物理内存 1/64,等价于 -XX:InitialHeapSize

2、-Xmx

最大分配内存,默认为物理内存的 1/4,等价于 -XX:MaxHeapSize

3、-Xss

设置单个线程栈的大小,一般默认为 512-1024k,等价于 -XX:ThreadStackSize

4、-Xmn

设置年轻代的大小

整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小

持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

5、-XX:MetaspaceSize

设置元空间大小

元空间的本质和永久代类似,都是对 JVM 规范中的方法区的实现。

元空间与永久代之间最大区别:元空间并不在虚拟机中,而是使用本地内存

因此默认情况下,元空间的大小仅受本地内存限制,元空间默认比较小,我们可以调大一点

6、-XX:+PrintGCDetails

输出详细GC收集日志信息

7、-XX:SurvivorRatio

设置新生代中 eden 和 S0/S1 空间比例,默认 -XX:SurvivorRatio=8,Eden : S0 : S1 = 8 : 1 :

8、-XX:NewRatio

配置年轻代和老年代在堆结构的占比,默认 -XX:NewRatio=2 新生代占1,老年代占2,年轻代占整个堆的 1/3

9、-XX:MaxTenuringThreshold

设置垃圾最大年龄

新生代与老年代参数比例设置

-XX:+PrintGCDetails -verbose:gc -XX:SurvivorRatio=2 -XX:NewRatio=1

GC日志参数分析

package com.taotao.jvm1.day08;

/**

*@author tom

*Date 2020/8/25 0025 10:07

*gc日志回收

* -XX:+PrintGCDetails -verbose:gc -XX:SurvivorRatio=2 -XX:NewRatio=1

*/

public class Test02 {

public static void main(String[] args) {

// -Xms20m -Xmx20m -XX:+PrintGCDetails -verbose:gc

//-Xms20m -Xmx20m -XX:+PrintGCDetails -verbose:gc

System.out.println("my");

}

}

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" -XX:+PrintGCDetails -verbose:gc "-javaagent:D:\program\idea\IntelliJ IDEA 2020.1\lib\idea_rt.jar=54958:D:\program\idea\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;F:\works\2020\mayiketang\7\jvm\jvm1\target\classes;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.3.2.RELEASE\spring-boot-starter-web-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\2.3.2.RELEASE\spring-boot-starter-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\2.3.2.RELEASE\spring-boot-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.2.RELEASE\spring-boot-autoconfigure-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.3.2.RELEASE\spring-boot-starter-logging-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\Administrator\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.3.2.RELEASE\spring-boot-starter-json-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.11.1\jackson-databind-2.11.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.1\jackson-annotations-2.11.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.11.1\jackson-core-2.11.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.1\jackson-datatype-jdk8-2.11.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.1\jackson-datatype-jsr310-2.11.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.1\jackson-module-parameter-names-2.11.1.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.2.RELEASE\spring-boot-starter-tomcat-2.3.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.37\tomcat-embed-core-9.0.37.jar;C:\Users\Administrator\.m2\repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.37\tomcat-embed-websocket-9.0.37.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\5.2.8.RELEASE\spring-web-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.2.8.RELEASE\spring-beans-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\5.2.8.RELEASE\spring-webmvc-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.2.8.RELEASE\spring-aop-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.2.8.RELEASE\spring-context-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.2.8.RELEASE\spring-expression-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.2.8.RELEASE\spring-core-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.2.8.RELEASE\spring-jcl-5.2.8.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\openjdk\jol\jol-core\0.9\jol-core-0.9.jar;C:\Users\Administrator\.m2\repository\org\projectlombok\lombok\1.18.10\lombok-1.18.10.jar" com.taotao.jvm1.day08.Test02

my

Heap

PSYoungGen total 75264K, used 6451K [0x000000076c800000, 0x0000000771c00000, 0x00000007c0000000)

eden space 64512K, 10% used [0x000000076c800000,0x000000076ce4ceb8,0x0000000770700000)

from space 10752K, 0% used [0x0000000771180000,0x0000000771180000,0x0000000771c00000)

to space 10752K, 0% used [0x0000000770700000,0x0000000770700000,0x0000000771180000)

ParOldGen total 172032K, used 0K [0x00000006c5800000, 0x00000006d0000000, 0x000000076c800000)

object space 172032K, 0% used [0x00000006c5800000,0x00000006c5800000,0x00000006d0000000)

Metaspace used 3441K, capacity 4496K, committed 4864K, reserved 1056768K

class space used 385K, capacity 388K, committed 512K, reserved 1048576K

Process finished with exit code 0

9f13fd26a9f5

image.png

9f13fd26a9f5

image.png

/**

* @ClassName Test001

* @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com

* @Version V1.0

**/

public class Test001 {

// -Xms20m -Xmx20m -XX:+PrintGCDetails -verbose:gc

//-Xms20m -Xmx20m -XX:+PrintGCDetails -verbose:gc

public static void main(String[] args) {

ArrayList mayiktList = new ArrayList<>();

// mayiktList.add(new byte[12 * 1024 * 1024]);

mayiktList.add(new byte[15 * 1024 * 1024]);

}

}

[GC (Allocation Failure) [PSYoungGen: 1626K->488K(6144K)] 1626K->688K(19968K), 0.0039387 secs] [Times: user=0.14 sys=0.00, real=0.00 secs]

新生代发生GC ,从堆内存回收前占用:1626k 回收后变为占用488K ,后面表示GC的用时。

[Full GC (Allocation Failure) [PSYoungGen: 488K->0K(6144K)] [ParOldGen: 296K->593K(13824K)] 784K->593K(19968K), [Metaspace: 3099K->3099K(1056768K)], 0.0043821 secs]

当发生老年代GC时,也会触发新生代GC,新生代堆回收前占用488K,回收后占用0K

,ParOldGen 老年代回收前占用784K,回收后占用593K

GC分析大对象

当我们直接存一个大的对象的时候,比新生代占用空间还有大时,会直接晋升为老年代。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值