目录

  • 1.GC调优预备知识
  • 2.GC调优领域与目标
  • 3.最快的GC是不发生GC
  • 4.新生代调优
  • 5.幸存区调优
  • 5.老年代调优

1.GC调优预备知识

预备知识
掌握 GC 相关的 VM 参数,会基本的空间调整
掌握相关工具
明白一点:调优跟应用、环境有关,没有放之四海而皆准的法则

查看虚拟机参数命令

"F:\JAVA\JDK8.0\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"

可以根据参数去查询具体的信息

ConGCThreads=0:CMS回收的并发线程数
GCTimeRatio=99:并行GC,与吞吐量相关的GC时间占领
MaxGCPauseMills:最大的GC停顿时间的目标

2.GC调优领域与目标

调优领域
内存
锁竞争
CPU占用
IO

确定目标:
低延迟还是高吞吐量,选择合适的回收器
CMS,G1
ParallelGC

如果是做科学运算,它们追求的是高吞吐量。对于延长一点点的响应时间,不是太紧要。如果做的是互联网项目,响应时间是非常重要的一环。
对于高吞吐量的垃圾回收器,只有ParallelGC,如果是低响应时间就选择CMS,G1
jdk9中G1取代了CMS,G1在更大的内存下,工作的效果比CMS更好。它继承了CMS与ParallelGC二者之长,特别适合管理超大内存的超大回收,既可以做到低延迟,也可以做到类似Parallel一样,追求吞吐量。

3.最快的GC是不发生GC

如果没有GC的发生,也就会没有stop the world,这样程序的性能也会一直保持快速的响应。如果经常发生GC,首先排除减少因为自身编写的代码而引发的内存问题

查看Full GC前后的内存占用,考虑以下几个问题
数据是不是太多?
加载了不必要的数据到内存,内存的数据太多,导致堆内存的压力过大
比如如下代码:resultSet=statement.query(“select * from 大表”);
写完了再去遍历结果集。如果执行这样一条查询,它就会把所有的数据读入到java内存,这样的话内存再大,它也顶不住这么多语句同时查询,导致堆内存过大。我们可以加上limit n
数据表示是否太臃肿
比如查询用户,不需要把用户所有信息都查询出来。有可能只是用到其中的一部分。
对象图
对象大小
java的最小一个对象都要占用16字节。Integer包装头也要用16字节。能用基本类型,就不用包装类型。
是否存在内存泄漏
static Map map=不断往里面放对象,可能会造成内存溢出。
第三方缓存实现,如redis,会有缓存过期。

4.新生代调优

只有排除了自己代码出现问题以后,再来进行内存调优。
内存调优一般从新生代开始
新生代的特点:

  • 所有的new操作分配内存都是非常廉价的
    .当new一个对象时,这个对象首先会在Eden伊甸园区分配,分配速度非常快。每个线程都会在伊甸园中分配一个私有区域TLAB thread-local allocation buffer,线程局部私有缓冲区。当new一个对象的时候,首先会减产TLAB中有没有可用内存,如果有,会在这块区域进行内存分配。TLAB 它的作用就是让每个线程用自己私有的伊甸园区来进行内存分配,这样多个线程即使同时创建对象,也不会有并发问题带来的干扰。
  • 死亡对象回收零代价
    注意:以前介绍的所有垃圾回收器新生代都是采用复制算法。即把伊甸园和幸存区From都复制到幸存区To中去,复制完了之后,它们的内存都被释放出来了,因此,死亡对象回收代价就是0
  • 大部分对象用过即死(朝生夕死)
    垃圾回收时,大部分对象都会被回收
  • MInor GC 所用时间远小于Full GC
    从而minor GC时间短,所以新生代优化空间更大一些

新生代内存越大越好么?
不是

新生代内存太小:频繁触发Minor GC,会STW,会使得吞吐量下降
新生代内存太大:老年代内存占比有所降低,会更频繁地触发Full GC。而且触发Minor GC时,清理新生代所花费的时间会更长

Oracle建议新生代占整个堆的1/4以上1/2以上的标准。


但是总的原则,我们还是要将新生代调的尽可能大,因为新生代垃圾回收用的是复制算法,复制算法分为两个阶段,1:标记,2.复制。复制花的时间更多一点。复制牵扯到对象占有内存的移动以及更新其它对象的内存地址。而新生代大部分对象都是朝生夕死的,只有少量的对象能够存活下来,那么复制所占用的时间较短,而标记时间相对复制时间来讲,就不是那么重要了。

设置多大合适:

新生代内存设置为内容纳[并发量(请求-响应)]的数据为宜*
即一次请求和响应中所产生的对象的大小乘以并发量。
比如一次请求和响应过程中会创建很多新的对象,这些新的对象占512K的内存,并发量大概是1000,即同一时刻有1000个用户来访问,那么新生代比较理想的内存就是每一个请求响应乘以并发量。即512K1000约为512M。因为这一次请求响应的过程以后大部分对象都会被回收,而这一次请求并发量所占用的内存不超过新生代的内存,就较少的触发新生代的垃圾回收。这样就可以大约估算出新生代内存占用大概划分为多少合理。

5.幸存区调优

幸存区需要能够保存 当前活跃对象+需要晋升的对象
幸存区中可以看到两类对象,一类对象生命周期较短,很快就会被回收掉,但是现在还在使用它,暂时不能回收。所以就会留在幸存区出。另一类是将来将会晋升到老年代,但是因为年龄还不够,所以暂存在幸存区中。所以幸存区的大小就需要大到能够把这两类对象都能容纳

如果幸存区比较小,它就会由JVM动态的调整晋升阈值,也许有些对象寿命还不够,但它存活时间并不是很长,由于幸存区内存太少,导致会提前把一些对象晋升到老年代中去。如果存活时间短的对象被晋升到老年代之后,那么它就要等老年代内存不足触发Full GC才能把它当成垃圾进行回收,这就间接的延长了对象的存活时间。我们要保证真正需要长时间存活的对象才把它晋升到老年代

晋升阈值配置得当,让长时间存活的对象尽快晋升
因为长时间存活的对象,一直留在幸存区,只能够耗费幸存区的内存。并且新生代的垃圾回收算法主要耗费时间就在对象复制上,如果有大量的长时间存活的对象不能及时的进程,它们就会被留在幸存区复制来赋值去,这样就会降低性能。所以我们应该设置晋升阈值,将晋升阈值调的比较小。将长时间存活的对象尽快调整到老年区
-XX:MaxTenuringThreshold=threshold
调整最大晋升阈值
-XX:+PrintTenuringDistribution
打印晋升的详细信息,以便判断晋升阈值是否更合适。

Desired survivor size 48286924 bytes, new threshold 10 (max 10)
- age 1: 28992024 bytes, 28992024 total
- - age 2: 1366864 bytes, 30358888 total
- - age 3: 1425912 bytes, 31784800 total ...

通过打印幸存区中不同年龄的对象打印,可以更细致的决定的把最大阈值调整到多少合适。

5.老年代调优

以 CMS 为例
CMS 的老年代内存越大越好

CMS垃圾回收器,是一种低响应时间的,并且是一个并发的垃圾回收器,即垃圾回收线程在工作的同时,其他的用户线程也能够并发的执行,但是这样有一个缺点,因为垃圾回收的同时,其他的用户线程也在运行,那么又会产生新的垃圾,如果浮动垃圾产生又导致内存不足,就会导致CMS并发失败,此时CMS垃圾回收器就不能正常工作了,因此它就会退化SerialOld串行垃圾回收器,然后就Stop the world.响应时间就会变得特别长。所以规划内存的时候就尽量大一点,这样就可以预留更多的空间,避免浮动垃圾引起的并发失败。
先尝试不做调优,如果没有 Full GC 那么已经…,否则先尝试调优新生代
如果没有引起Full GC,那么说明老年代的空间比较充裕,这种没有Full GC,说明系统工作的很OK了。即便发生了FullGC,也从新生代开始调试。如果还是经常发生Full GC,那么就开始老年代调优
观察发生 Full GC 时老年代内存占用,将老年代内存预设调大 1/4 ~ 1/3
-XX:CMSInitiatingOccupancyFraction=percent
控制老年代内存被占用多少了之后,使用CMS进行垃圾回收。这个值越低,老年代垃圾回收触发的时机就越早。

JVM学习-垃圾回收调优相关推荐

  1. JVM day05_06 垃圾回收调优 类加载

    垃圾回收调优 新生代调优 特点 TLAB即线程本地分配缓存区,这是一个线程专用的内存分配区域.作用是每个线程先在自己私有的与伊甸园分配内存,不会被其他线程所干扰 新生代内存设置越大越好吗 不是,新生代 ...

  2. 【转】Java内存与垃圾回收调优

    要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...

  3. JVM学习-垃圾回收基础

    垃圾回收基础 1.判断垃圾是否可被回收 1.1.引用计数法 1.2.可达性分析算法 2.五种引用 2.1.强引用 2.2.软引用 2.2.1.软引用介绍 2.2.2.软引用应用 2.3.弱引用 2.4 ...

  4. Java 14 Hotspot 虚拟机垃圾回收调优指南!

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 大鹏123 来源 | www.cnblogs. ...

  5. Java垃圾回收调优

    在Java中,通常通讯类型的服务器对GC(Garbage Collection)比较敏感.通常通讯服务器每秒需要处理大量进出的数据包,需要解析,分解成不同的业务逻辑对象并做相关的业务处理,这样会导致大 ...

  6. java 指定垃g1圾收集_【译】Java 14 Hotspot 虚拟机垃圾回收调优指南

    本文主要包括以下内容:优化目标与策略(Ergonomics) 垃圾收集器实现(Garbage Collector Implementation) 影响垃圾收集性能的因素总堆(Total Heap) 年 ...

  7. JVM整体架构与调优参数说明

    本文来说下JVM整体架构与调优参数说明 文章目录 概述 JVM的分类 JVM的构成 方法区(元空间) 堆 栈 本地方法栈 程序计数器 JVM调优参数 本文小结 概述 很多小伙伴都认为JVM的知识很难, ...

  8. 大数据技术之_19_Spark学习_07_Spark 性能调优 + 数据倾斜调优 + 运行资源调优 + 程序开发调优 + Shuffle 调优 + GC 调优 + Spark 企业应用案例

    大数据技术之_19_Spark学习_07 第1章 Spark 性能优化 1.1 调优基本原则 1.1.1 基本概念和原则 1.1.2 性能监控方式 1.1.3 调优要点 1.2 数据倾斜优化 1.2. ...

  9. 史上最全JVM整体架构和调优参数说明,带你彻底理解JVM整体架构与调优技巧

    大家好,我是冰河~~ 从今天开始,我们正式开始<架构师进阶系列>技术文的更新,在<架构师进阶系列>中,我们首先一起来探讨有关JVM的知识. 很多小伙伴都认为JVM的知识很难,很 ...

最新文章

  1. ICRA2022 | AutoPlace:车载单片毫米波雷达场景识别
  2. 前嗅ForeSpider教程:创建模板
  3. 计算机环境安全服务未启动,windows10系统卡在“准备安全选项”如何解决
  4. 实现一个行内三个div等分_css 实现等分布局
  5. Python无限播放励志语句
  6. jumpserver 0.4.0 安装使用
  7. linux mysql更改表字段_MySQL 修改表字段优化方案
  8. win7怎么把计算机放到桌面6,手机投屏到电脑win7最简单具体操作步骤
  9. vue改变class名字_vue添加class类名
  10. 支付宝接口 设置支付宝订单的超时时间为15分钟
  11. 赛尔号眼球怎么抓_素描头像怎么画?素描入门基础画|自学素描基本入门教程...
  12. 17 岁成为 iOS 越狱之父,25 岁造出无人车,黑客传奇!
  13. rtl8188linux内核配置,编译基于rtl8188cu控制芯片的USB无线网卡在Linux下的配置
  14. 计算机x线影像ppt,计算机X线摄影课件
  15. AtCoder Beginner Contest 236 A-D题解
  16. 最新苹果手机备份同步工具 iMazing2.16.4官方免费下载
  17. mysql8.0.19中在navicat客户端中int、bigint等类型设置长度保存后为0
  18. 2020-09-23
  19. MySQL函数(经典收藏)
  20. 数据结构 - JS实现二叉树

热门文章

  1. 软件自动化测试面试三部曲:第三是经验,第二是技术,第一是...
  2. java wait 释放_Java:wait()从同步块释放锁
  3. 一种RTP接收和解包的程序
  4. ffmpeg 花屏的问题
  5. Golang实践录:获取系统信息
  6. 嵌入式Linux入门8:rootfs移植
  7. FTP主动模式和被动模式学习笔记
  8. 深度学习入门:Day-12
  9. 《转》Unsafe与CAS
  10. 气体管道管径及流量对照表_建筑用管道产品常见技术质量问答汇总