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 ...
随机推荐
- python 异步请求
这是循环请求10次页面.总时间大概是10秒左右,如果是普通的循环请求10次页面而不添加异步的话,时间大概在30秒以上,当然这个数据可能有误,因为有网速的问题存在,但大体的效果应该是不变的. impor ...
- Linux系统之LNMP及nginx反向代理实现
1.编译安装LNMP,并安装wordpress 首先准备环境,编译安装LNMP可以是多台主机,也可以是单台主机,把nginx,mysql,php都集中安装在一个主机上:我这里以一台主机为例吧!! 一. ...
- (转)bss段和.data的是是非非
原文地址:http://zqwt.012.blog.163.com/blog/static/12044684201101214457186/ 一般情况下,一个程序本质上都是由 bss段.data段.t ...
- require.context('.', true, /\.router\.js/) webpack 编译的时候读取目录文件
const routerList = [] function importAll (r) { r.keys().map(value => { r(value).default.map(item ...
- JavaScript 模式》读书笔记(3)— 字面量和构造函数3
这是字面量和构造函数的最后一篇内容,其中包括了JSON.正则表达式字面量,基本值类型包装器等知识点.也是十分重要的哦. 五.JSON JSON是指JavaScript对象表示以及数据传输格式.它是一种 ...
- LoadRunner录制HTTPS协议脚本
学习LoadRunner录制HTTPS协议脚本,其实是一个意外的收获.当我拿到要测试的URL时,我像以前的步骤一样录制脚本,但是录制结束后,发现并没有生成脚本,开始以为是LoadRunner的原因,我 ...
- WebStorm添加Angular2服务启动的脚本命令
注意:选择的start在package.json可以修改. 例如添加一个run命令:
- 微信开发+百度AI学习:植物识别
直接上代码 服务端代码如下 private static readonly Baidu.Aip.ImageClassify.ImageClassify client = new Baidu.Aip.I ...
- 关于Web2.0
前言:本来是想写HTML的,发现没什么好写的,就简单写一下Web2.0好了 什么是Web 2.0: "Web 2.0 is the business revolution in the co ...
- 洛谷1074 靶状数独dfs 排序、记录、搜索
题目网址:https://www.luogu.com.cn/problem/P1074 大意就是在一个9*9的数独中填数,要求行列宫都是九个互不相同的数字,给定一定的得分机制,要求求解最大得分.思路大 ...