JVM 理解性学习(一)
重新学习,重新理解
1、类加载过程等
验证:.class 文件加载到 JVM 里的时候,会验证下该文件是否符合 JVM 规范。
准备:给实体类分配内存空间,以及给类变量(static 修饰)分配"默认值"。
解析:将符号引用替换为直接引用。
初始化:将类初始化,如果有父类且父类未初始化,会先初始化父类,再初始化此类。然后再对各个变量赋值。
一个线程一个虚拟机栈,一个方法对应一个栈帧,栈帧里存了局部变量等信息。
程序计数器主要是记录当先线程执行到的字节码位置。
2、JVM 参数设置
java -Xms512M -Xmx512M -Xmn256M -Xss1M -XX:PermSize=128M -XX:MaxPermSize=128M -jar App.jar
堆内存和最大内存512M,新生代256M,栈内存1M,元数据内存和最大内存128M。
3、四种引用
引用:一个引用指向一个堆中的对象。
强引用:还有局部变量或者静态类变量等指向对象,此时该对象不可被回收(任意情况)。
软引用:如果堆中新生代内存满了,发生 minorGC,就会回收该软引用。
4、新生代3区的思想
将新生代分为3个区 Eden 区,2个 Survivor 区。用到了复制算法,而一般情况下,MinorGC 后存活的对象只有垃圾回收之前的1%。 所以三个区的比例一般是8:1:1。
当 Eden 区对象占满了内存,触发 MinorGC ,就会把存活对象放在一个 Survivor 区,然后清除 Eden 区。
当发生第二次 MinorGC 时,就会把 Eden 区和存了对象的 Survivor 区的存活对象,放到第二个 Survivor 区。然后清除 Eden 区和第一个Survivor 区的死亡对象。
5、新生代对象进老年代对象的几种情况
1)、躲过15次 minorGC 之后从新生代进入老年代;
2)、大对象直接进入老年代。有一个 JVM 参数 '-XX:PretenureSizeThreshold' 设置值为字节数,创建超过该大小的对象直接进入老年代。
3)、动态年龄判断:当前放对象的 Survivor 区,相同年龄的一批对象(以及小于该年龄)的总内存大于该区的内存的50%,大于该年龄的其他老对象,就会进入老年代(例如1,2,3岁年龄的对象占了 S 区的50%以上,就会把大于3岁的对象移动到老年代去。所以尽量让 S 区中的对象,占比尽量少于 50%);
4)、Eden 区存活对象太多,超过了 Survivor 的大小,就直接把这些对象都转移到老年代去。(空间担保机制)
3、4点是可能造成频繁 FullGC 的原因。
老年代内存分配担保规则:在执行一次 MinorGC 之前,JVM 会先检查一下老年代可用的内存空间,是否大于新生代所有对象的总大小。小于也没有关系,只要开启了担保规则,就不会关注于新生代所有对象的大小,而会关注新生代多次 MinorGC 的回收垃圾对象的平均大小。
触发 FullGC:
Survivor 区域放不下每次 MinorGC 后存活的对象,所以直接放入了老年代,以至于没发生几次 MinnoGC 后,就会触发 FullGC。
假如老年代可用内存小于新生代所有对象的大小,就会检查一个参数是否设置。设置后,遵循老年代空间分配担保原则,就会检查老年代的内存大小,是否大于之前 MinorGC 后进入老年代的对象的平均大小。
如果判断失败,或者没有设置参数,就会触发 FullGC。
尽量少 FullGC 思路:
1)、将对象在新生代存活年龄又15变大,改为30或更大;
2)、禁止对象动态年龄,防止对象还未活到30次 MinorGC 就移到老年代;
3)、将新生代占的内存空间调大,并且将 Surivivor 区域调大。保证每次 MinorGC 后存活的对象能放在 Surivvor 区域,不会因为 Survivor 区域过小,直接将对象放老年代。
6、ParNew 和 CMS 垃圾回收器
多线程并发的机制,性能更好,一般是线上生产系统的标配。
JVM 优化,指 减少垃圾回收的频率,降低垃圾回收的时间,减小垃圾回收对系统运行的影响。
Stop th World :在垃圾回收的时候,停止系统的运行,停止对象的创建。
ParNew:多线程垃圾回收机制。在合适的时机执行 MinorGC,停止程序运行,禁止程序继续创建对象,用多个垃圾回收线程去回收垃圾对象。(多线程是为了适应 多核 CPU)
指定参数: XX:+UsePerNewGC ,JVM 启动,新生代就是用 PerNew 垃圾回收器了。
CMS:标记清理算法,采取的是垃圾回收线程和系统工作线程,尽量同时执行的模式来处理的。
分为四个阶段:初始标记、并发标记、重新标记、并发清理。
初始标记:让系统的工作线程全部停止,进入 "Stop the World" 状态。去标记 GC Roots,方法的局部变量和类的静态变量是 GC Roots,类的实例变量不是 GC Roots。(暂停工作线程的速度很快,只是为了标记 GC Roots 直接引用的变量) (标记活着的---有引用的对象)
并发标记:对老年代所有的对象都进行 GC Roots 追踪,是最耗时的。追踪所有对象是否从根源上被 GC Roots 引用了。但是最耗时的垃圾回收线程,是和系统运行的线程并发进行,所以不影响系统。(因为老年代大多数对象都是存活的)
重新标记:让系统停下来,进入 "Stop the World" 阶段。重新标记下第二阶段新创建的对象,还有一些已有对象可能失去引用,变成垃圾对象。(再找到活着的少部分,其他都是垃圾对象)
并发清理:很耗时,清理之前标记为垃圾的对象即可。(之前标记了存活和垃圾)垃圾回收线程,也是和系统运行线程并发执行。
真正耗时的第二和第四阶段,是和工作线程并发进行。第一和第三阶段,虽然停止了工作线程,但是工作内存不多,不太耗时。
CMS 并发垃圾回收机制会有几个问题:
第一个问题:消耗 CPU 资源。
第二个问题:在垃圾回收的时候,会新产生浮动垃圾对象,如果该对象占内存超过了老年代预留的内存,就会发生 Concurrent Mode Failure ,并发失败,执行 Serial Old 垃圾回收器,强行 Stop th World。
第三个问题:内存碎片问题。Full GC 后再次 Stop the World ,停止工作线程,整理碎片。把存活对象移到一起。
所以为什么 FullGC 比 MinorGC 要慢10倍还多,主要就是算法的不同,以及 FullGC 后还进行内存整理。
-XX:CMSInitiatingOccupancyFaction 参数可以设置老年代中对象占多少比例的时候,触发 CMS 垃圾回收器的回收机制,默认92%。
个人学习以及总结
1、如果新生代中对象太多,并且老年代可用内存不是很大(新生代对象内存 > 老年代可用内存),没有空间担保规则,那么就会频繁出发 FullGC。
2、MinorGC 很快的原因:采用复制算法,一次 MinorGC 存活的对象少,迁移的存活对象就少,迁移就快。迁移完存活对象后,就直接清理垃圾对象,速度就快。
3、并发标记:怎么一边标记存活对象,一边标记垃圾对象。就是在垃圾回收线程工作的同时,让系统线程也运行。这样有引用的就是存活对象,没有引用的就是垃圾对象。(主要是标记垃圾对象,所以会产生浮动垃圾)
4、为什么优化 JVM:内存分配、参数设置不合理,导致对象频繁进入老年代,频繁触发老年代 FullGC,导致系统每个几分钟就要停顿几秒。
5、YGC 就算频繁一些,也不会对系统产生很大影响。主要还是 FullGC 对系统的停顿时间太长。
JVM 理解性学习(一)的更多相关文章
- JVM 理解性学习(二)
1.G1 垃圾回收器 G1 能更少的 "Stop the World" ,能同时对新生代老年代进行垃圾回收. G1 将 Java 堆内存拆分为多个大小相等的 Region,并且新生 ...
- JVM类加载过程学习总结
JVM类加载过程学习总结 先不说JVM类加载的原理,先看实例: NormalTest类,包含了一个静态代码块,执行的任务就是打印一句话. /** * 在正常类加载条件下,看静态代码块是否会执行 * @ ...
- 利用Theano理解深度学习——Multilayer Perceptron
一.多层感知机MLP 1.MLP概述 对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logi ...
- Linux系统的理解及学习Linux内核的心得
作业列表 (点击作业跳转) linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作 linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核 ...
- 关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)
关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录) 作者:王可利(Star·星星) HTML中 相对定位:position:relative; 绝对定位:position ...
- map和flatmap的区别+理解、学习与使用 Java 中的 Optional
转自:map和flatmap的区别 对于stream, 两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...
- 从极大似然估计的角度理解深度学习中loss函数
从极大似然估计的角度理解深度学习中loss函数 为了理解这一概念,首先回顾下最大似然估计的概念: 最大似然估计常用于利用已知的样本结果,反推最有可能导致这一结果产生的参数值,往往模型结果已经确定,用于 ...
- torchvision的理解和学习 加载常用数据集,对主流模型的调用.md
torchvision的理解和学习 加载常用数据集,对主流模型的调用 https://blog.csdn.net/tsq292978891/article/details/79403617 加载常用数 ...
- 深入理解JVM(③)学习Java的内存模型
前言 Java内存模型(Java Memory Model)用来屏蔽各种硬件和操作系统的内存访问差异,这使得Java能够变得非常灵活而不用考虑各系统间的兼容性等问题.定义Java内存模型并非一件容易的 ...
随机推荐
- 01-if条件语句之数字比较
if条件语句之数字比较 #!/bin/bash # 使用expr命令,比较结果正确,输入1,错误输入0 expr_mode(){ if [ $(expr $1 \<\= $2) -eq 1 ]; ...
- 工作了这么长时间,是不是非用macbook pro不可呢?
连续奋战了二十多天,肉眼可见自己的状态一天不如一天.总觉得自己是不是该放下一切好好休息两天,但是理智又告诉我不能停.不能停. 既然不能停,那就把之前攒下的文章写一写吧. 什么是macbook pro ...
- Core + Vue 后台管理基础框架8——Swagger文档
1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...
- Hive 时间操作
Hive 时间转换 UNIX时间戳概念:因为UNIX时间戳只是一个秒数,一个UNIX时间戳在不同时区看来,时间是不同的.如UNIX时间戳0,在0时区看来是1970-01-01 00:00:00,在东八 ...
- 201771010103 陈亚茹 《面向对象程序设计(java)》第一周学习总结
本人学号<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com https://w ...
- P1969 积木大赛 题解
原题链接 简要题意: 每次把一段区间 \(+1\),问得到 \(a\) 数组的最小次数. 我们可以把 \(+1\) 得到 \(a\) 换成,从 \(a\) 依次 \(-1\) 得到 \(0\). 算法 ...
- 题解 P2642 【双子序列最大和】
前言 其实这道题的关键就是在于预处理,其方法类似于 合唱队形 正文 求最大子段和 要想求出双子序列最大和,首先我们要会求出最大子段和 最大子段和的求值方法很简单 定义 \(f_i\) 为以第 \(i\ ...
- [模板] LCA-最近公共祖先-倍增法
2019-11-07 09:25:45 C.树之呼吸-叁之型-树上两点路径长度 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 7 (4 ...
- IOS(苹果手机)使用video播放HLS流,实现在内部播放及全屏播放(即非全屏和全屏播放)。
需求: 实现PC及移动端播放HLS流,并且可以自动播放,在页面内部播放及全屏播放功能. 初步:PC及安卓机使用hls.js实现hls流自动播放及全屏非全屏播放 首先使用了hls.js插件,可以实现在P ...
- Python第五章-内置数据结构01-字符串
Python 内置的数据结构 到目前为止,我们如果想保存一些数据,只能通过变量.但是如果遇到较多的数据要保存,这个时候时候用变量就变的不太现实. 我们需要能够保存大量数据的类似变量的东东,这种 ...