JVM 理解性学习(二)
1、G1 垃圾回收器
G1 能更少的 "Stop the World" ,能同时对新生代老年代进行垃圾回收。
G1 将 Java 堆内存拆分为多个大小相等的 Region,并且新生代和老年代只是逻辑上的概念。
最大的特点:设置一个垃圾回收的预期停顿时间。可以让 G1 垃圾回收器保证达到开发人员手动设置的 "Stop the World" 的时间。
G1 对垃圾回收导致的系统停顿可控:追踪每个 Region 里的回收价值。就是清楚每个 Region 里的对象多少是垃圾,如果对该 Region 进行垃圾回收,需要耗费多少时间,回收多少垃圾对象。
停顿时间参数: -XX:MaxGCPauseMills,默认200ms。
核心思想:设定了垃圾回收的预期停顿时间后,G1 尽量控制在设置的时间范围内,最少回收时间,回收更多的垃圾。
JVM 最多有2048个 Region,Region 的大小必须是2的倍数。Region 新生代和老年代占比其实是动态变化的,新生代初始默认5%,最大默认60%。
触发垃圾回收,还是 Eden 区占满了对象。除了停顿时间是预设的,其垃圾回收过程是和新生代垃圾回收过程 PerNew一样。
对象从新生代进入老年代,也是和 CMS 垃圾回收器的机制相同,除了大对象。因为会专门分配 Region 来存大对象。(一个对象的大小超过一个 Region 内存的50%)
混合回收:前三步操作和 CMS 回收相似。只有最后一步是混合回收,多次停顿回收,复制 region,并且清除对象。Full GC 失败也和 CMS 回收相相似,变为单线程回收,并Stop the World。
在老年代占内存的45%开始混合回收 MixedGC,并且也会回收大对象。
小总结:一些负载很低的系统,JVM 本身是没什么必要调优的。没有复杂度和高负载的系统,JVM 一般很少会出现问题。
适合 G1 回收器的场景:追求低延迟的场景,或者大内存机器。(内存太大,如果常规垃圾回收器,就会一次性回收很多垃圾,停顿时间过长)
2、JVM 调优实战
学会看 GC 日志,与分析 GC 日志。
当 Survivor 区域存放不下 Eden 区存活的对象时,Eden 区存活的对象,一部分会移动到老年代,一部分会移动到 Survivor 区。
通过 jstat -gc PID de 命令,可以分析出一些数据:
新生代增长的速率(观察 eden 区的被占用内存的变化);
YGC 触发的频率(多久触发一次 YGC);
YGC 的耗时;
每次 YGC 后有多少对象存活下来(发生YGC 后看 survivor 区新增对象的大小);
每次 YGC 过后有多少对象进入老年代(发生 YGC 后看老年代新增对象的大小);
老年代增长的速率;
FGC 触发频率;
FGC 的耗时。
3、极高QPS怎么优化 JVM
思路:
用 jstat 分析一下 JVM 运行情况,判断每次 YGC 后存活对象有多少,增加 Survivor 区的内存,避免对象快速进入老年代。
但是老年代还是会发生 FullGC,这时就需要整理老年代的内存碎片。
分析:
1)、极高QPS,则会迅速产生对象,迅速占满 Eden 区,则进行 YGC。而进行 YGC 的时候,同时又有很多请求产生对象,则会有很多对象在 YGC 的时候存活。
2)、如果存活的对象很多,则可能导致 Surivivor 区装不下存活对象,就会导致对象大量进入老年代。则会频繁出发 OGC。
3)、在 OGC 的时候,因为回收算法是标记-清理算法,则会在老年代中产生大量内存碎片。
解决:
1)、参数:-XX:+UserCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5 可以把5修改为0。含义是在发生几次 FullGC 后,对老年代的内存碎片进行整理,空出大量内存空间。
因为内存碎片还会导致 FullGC 的频率,因为内存碎片会越来越多,能放下的对象越来越少。
2)、参数:-XX:+CMSparallellnitialMarkEnabled,这个参数会在 CMS 垃圾回收器的 初始标记 阶段开启多线程并发执行。主要是减少 Stop the world 的时间。
3)、参数:-XX:+CMSScavengeBeforeRemark,这个参数会在 CMS 的重新标记阶段前进行一次 YGC。回收一些年轻代里没有人引用的对象,减少 CMS 在重新标记阶段扫描的对象,减少耗时。
4、JVM 的一些参数整理
-XX:CMSInitiatingOccupancyFraction=92 和 -XX:+UseCMSInitiatingOccupancyOnly 配套使用。如果仅设置前者,CMS 垃圾回收器第一次会采用内存占老年代 92% 但是后续会根据运行时采集的数据来进行 GC 周期。设置了后者,就会每次固定在内存占老年代 92% 时进行垃圾回收。
-XX:CMSParallellnitialMarkEnabled 表示在初始标记阶段,多线程执行以减少 STW;
-XX:CMSScavengeBeforeRemark 表示在重新标记阶段之前,执行 MinorGC 减少重新标记的时间;
-XX:CMSParallelRemarkEnable 表示在重新标记阶段,多线程执行以减少 STW;
5、小总结
频繁出发 FullGC de 三种可能:
1)、内存分配不合理,导致对象频繁进入老年代;(Survivor 过小,或者新生代过小,并且未开启空间担保规则,开启了动态年龄判断)
2)、存在内存泄露等问题,就是内存里驻留了大量的对象塞满了老年代,导致稍微有一些对象进入老年代就触发 FullGC;
3)、永久代里的类太多,触发了 FullGC。
JVM 理解性学习(二)的更多相关文章
- JVM 理解性学习(一)
重新学习,重新理解 1.类加载过程等 验证:.class 文件加载到 JVM 里的时候,会验证下该文件是否符合 JVM 规范. 准备:给实体类分配内存空间,以及给类变量(static 修饰)分配&qu ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- JVM实用参数(二)参数分类和即时(JIT)编译器诊断
JVM实用参数(二)参数分类和即时(JIT)编译器诊断 作者: PATRICK PESCHLOW 原文地址 译者:赵峰 校对:许巧辉 在这个系列的第二部分,我来介绍一下HotSpot J ...
- 利用Theano理解深度学习——Multilayer Perceptron
一.多层感知机MLP 1.MLP概述 对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logi ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- JVM类加载过程学习总结
JVM类加载过程学习总结 先不说JVM类加载的原理,先看实例: NormalTest类,包含了一个静态代码块,执行的任务就是打印一句话. /** * 在正常类加载条件下,看静态代码块是否会执行 * @ ...
- JVM 字节码(二)方法表详解
JVM 字节码(二)方法表和属性表 上一节中对 ClassFile 的整体进行了五个详细的说明, 本节围绕 ClassFile 最重要的一个内容 - 方法表的 Code 属性展开 ,更多 JVM Me ...
- JVM 内部原理(二)— 基本概念之字节码
JVM 内部原理(二)- 基本概念之字节码 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - Java Runtime Enviro ...
随机推荐
- Numpy之数据保存与读取
在pandas使用的25个技巧中介绍了几个常用的Pandas的使用技巧,不少技巧在机器学习和深度学习方面很有用处.本文将会介绍Numpy在数据保存和读取方面的内容,这些在机器学习和深度学习方向也大 ...
- const 详解
简单分类: 常变量 const 类型 变量名 或者 类型 const 变量名 常引用 const 类型& 引用名 ...
- Java并发编程之验证volatile不能保证原子性
Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...
- linux下查看系统版本
工作中我们会遇到安装软件需要知道linux是什么发行版本,话不多话上干货(按照我认为常用排序) 1. lsb_release -a 名词解释:LSB (Linux Standard Base) # 如 ...
- 爬虫 | cnblog文章收藏排行榜(“热门文摘”)
目录 需要用的module 单页测试 批量抓取 数据保存 背景说明 因为加入cnblog不久,发现上面有很多优秀的文章. 无意中发现cnblog有整理文章的收藏排行榜,也就是热门文摘. 不过有点坑的是 ...
- iOS开发:判断iPhone是否是刘海屏iPhoneX、iPhoneXR、iPhoneXs、iPhoneXs Max等
保证能判断,呕心沥血,不行切JIJI 方法一 Objective-C // iPhoneX.iPhoneXR.iPhoneXs.iPhoneXs Max等 // 判断刘海屏,返回YES表示是刘海屏 - ...
- Journal of Proteome Research | 人类牙槽骨蛋白的蛋白质组学和n端分析:改进的蛋白质提取方法和LysargiNase消化策略增加了蛋白质组的覆盖率和缺失蛋白的识别 | (解读人:卜繁宇)
文献名:Proteomic and N-Terminomic TAILS Analyses of Human Alveolar Bone Proteins: Improved Protein Extr ...
- [Docker4] Docker-machine进行多docker host管理
Docker Machine Docker machine就是自动化安装docker daemon Docker machine的provider docker machine provider 常见 ...
- spring boot项目打war包
1.如果有本地依赖,添加本地依赖到maven <!--lib目录下的jar包--> <dependency> <groupId>com.dm</groupId ...
- 【笔记3-31】Python语言基础-元组tuple
创建元组 my_tuple = () my_tuple1 = 1, 2, 3, 4, 5, 6 元组解包 与元组元素数量一致 a,s,d,f,g,h = my_tuple1 a, b, c, *f = ...