《深入理解Java虚拟机第3版》垃圾收集器与内存分配策略、虚拟机性能监控故障处理工具
目录
- 往期博客:Java课堂篇3_初识JMM、常量池简单理解(字符串常量池、静态常量池、大整型常量池)
- 为什么要了解垃圾收集和内存分配?
- 如何判断对象已死?
- 引用计数算法
- 可达性分析算法
- JDK1.2之后引用的扩充
- 回收方法区
- 垃圾收集算法分代收集理论
- 标记清除
- 标记复制
- 标记整理
- 对象分配
- 虚拟机性能监控故障处理工具
1、为什么需要了解垃圾收集和内存分配?
当需要排查各种内存溢出、内存泄露问题时,当垃圾收集成为系统达到高并发量的瓶颈时,我们必须对这些“自动化”的技术实
施必要的监控和调节。
2、如何判断对象已死?
2.1、引用计数法
- 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,当有一个地方取消引用它时,计数器值减1
- 虽然额外占用内存空间,但是他的原理简单,判定效率也很高
- Java领域主流的虚拟机未采用没有选择用,因为这个看似简单的算法有很多例外的情况要考虑,必须配合额外的大量处理才能确保正确工作,如单纯的引用计数很难解决对象之间的互相引用问题。
2.2、可达性分析
- 通过一系列的GC Roots的根对象作为起始点集,从这些结点开始,根据引用关系向下搜索,搜索走过的路径称为引用链,如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是不可达,证明这个对象不再被使用
- 固定可以作为GC Roots的对象包括:
- 虚拟机栈引用的对象(方法参数、局部变量、临时变量)
- 方法区的静态属性引用的对象
- 方法区的常量池引用的对象
- 本地方法栈Native方法引用的对象
- 虚拟机内部的引用
- 同步锁synchrionized持有的对象
2.3、JDK1.2之后引用的扩充
四种新扩充的引用
- 强引用:传统的"引用"定义如
Object o = new Object()
,只要强引用的关系还在,垃圾收集器就永远不会回收掉被引用的对象 - 软引用:描述还有用,但是非必须的对象,在系统将要发生内存溢出异常前,会把这些对象列入回收范围之中进行二次回收,如果回收之后还是内存不够,就会抛出异常。JDK1.2版之后提供了SftReference类来实现软引用
- 弱引用:也是描述那些非必须的对象,但是它的强度比弱引用更弱一些,被弱引用引用的·对象只能生存到下一次垃圾收集发生为止。
- 虚引用:不对对象存活造成影响,位一各对象设置虚引用的目的只是为了垃圾收集器回收该对象时收到有个系统通知。
3、回收方法区
- 相比于堆内存的回收,方法区的回收由于苛刻的回收条件,其区域垃圾收集的成果往往很低
- 方法区的垃圾收集主要涉及两部分的内容:
- 废弃的常量:字符串常量池里面的常量等
- 不在使用的类型:类、接口、方法、字段的符号引用等
- 判断一个类不在使用需要考虑
- 该类的所有实例都已经被回收
- 加载该类的类加载器已经被回收
- 该类对java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法
- 在大量使用反射、动态代理、CGLIB等字节码的框架,动态生成JSP等这类频繁自定义类加载器的场景,通常都需要Java虚拟机具备类型卸载的能力,以保证不会对方法区造成过大的内存压力。
4、垃圾收集算法
垃圾收集算法可以划分为
- 引用计数式垃圾收集(对应前面的 引用计数算法)
- 追踪式垃圾收集(对用前面的 可达性分析算法)
分代收集设计原则
- 弱分代假说:任何对象都是朝生夕灭
- 强分代假说:熬过越多次垃圾收集的对象就越难消亡
因此存在
- 部分收集Partical GC
- 新生代收集Young GC
- 老年代收集Old GC
- 混合收集Mixed GC
- 整堆收集Full GC
4.1、标记清除算法
算法分为 标记 和 清除 两个阶段
- 标记:首先标记出所有要回收的对象(或者存活的对象),在标记完成后
- 清除:统一回收掉被标记的对象
缺点
- 执行效率不太稳定:如果Java堆中包含大量对象,而且其中大部分都是需要回收的,这时需要大量标记和清除操作
- 内存空间碎片化问题:清除之后,产生大量不连续的内存空间,当需要分配大对象是,有可能放不下还需要进行一次GC
4.2、标记复制算法
相比标记清除算法
- 半区复制:将内存容量划分为大小相等的两块,每次只使用其中的一块,当这一块内存用完了,就还将存活的对象复制到另外一块,再把使用过的一块内存全部回收清理。
- 缺点:这种算法产生大量的内存空间复制的开销,可用内存缩小为原来的一半,空间浪费。
半区复制分代策略
- Appel式回收:虚拟机的新生代使用此种回收算法,将新生代分为 Eden和Survivor区域,比例为8:1:1;每次将Eden的存活对象放到Survivor中
- 需要老年代内存担保,也就是Survivor需要像老年代传送对象。
4.3、标记整理算法
相比于新生代使用标记复制算法、标记清除算法
- 老年代不能使用标记复制算法,因为老年代对象存活率高,进行复制会浪费内存空间
- 针对老年代对象的死亡特征,需要使用标记-整理算法,区别于标记-清除算法本质区别就是 不是直接对可回收对象清理,而是将存活的对象往一段移动,清除边界以外的内存。
特点
- 移动存活对象的·时候,尤其是老年代,移动对象地址需要全部用户程序才能进行Stop The World
- 不移动时候采用标记清除算法,内存分配复杂
- 移动的时候采用标记整理算法,回收时更复杂
- 有一种和稀泥方式,碎片化程度到达一定程度开启移动
5、对象分配
对象的内存分配从概念上讲都是堆上分配,(实际可能有即时编译后被拆散为标量类型并间接的在栈上分配),在经典分代的设计下,新生对象会直接分布在新生代,一些超过阈值的大对象可以直接分布在老年代
- 对象优先在Eden分配:没有足够空间会触发YoungGC,存活的对象会进入Survivor
- 大对象直接进入老年代:为了避免大对象内存复制的开销,直接将大对象分配到老年代,通过设置
-XX:PretenureSizeThreshold=3145728
参数指定阈值 - 长期存活的对象进入老年代:虚拟机给每个对象定义了一个对象年龄(Age)计数器存储在对象头中,对象通常在Eden单上,如果第一次经理YongGC能够存活下来并且Survivor能够放的下,该对象就会被移动到Survivor并且年龄加1岁,当年龄增加到一定程度(默认15岁)就会被放到年代。可以通过
-XXMaxTenuringThreshold
设置 - 动态对象年龄判断:除了对象年龄增长进入老年代,如果Survivor空间相同年龄的对象综合大于Survivor空间的一半,年龄大于等于该年龄的对象可以直接进入老年。
- 空间分配担保:在发生YoungGC的时候,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,
- 如果这个条件成立,那么这一次GC是确保安全的
- 如果这个条件不成立,则虚拟机会检查参数
-XX:HandlePromotionFailure
参数是否允许担保失败,如果允许,则会检查老年代可用连续空间是否大于历届上升到老年代对象年龄的平均大小- 如果大于,进行一次YoungGC
- 如果小于,或者是
-XX:handlePromotionFailure
设置不允许冒险,这时候就需要进行一次FullGC
6、虚拟机性能监控故障处理工具
6.1基础故障处理工具
jsp:虚拟机进程状况工具
虚拟机进程查看定位工具
jstat:虚拟机统计信息监视工具
显示类加载、内存、垃圾收集器、即时编译等运行时数据,定位虚拟机性能问题
参数参考:https://blog.csdn.net/ouyang111222/article/details/53688986jinfo:Java配置信息工具
jmap:Java内存映像工具
用于生成堆转储快照jhat:虚拟机堆转储快照分析工具
jstack:Java堆栈跟踪工具
jcmd:Java7开始提供的虚拟机诊断命令工具
基本Java工具
- javadoc:API文档生成器
- javap:字节码分析工具
6.2可视化故障处理工具
- jhsdb:Java9开始提供的进程调试器,基于服务代理的调试工具
首先使用jps查看进程号,然后jhsdb hsdb --pid xxx
进行操作 - JConsole:Java监视与管理控制台
控制台输入jconsole,本地、远程进行连接 - VisualVM:多合-故障处理工具
《深入理解Java虚拟机第3版》垃圾收集器与内存分配策略、虚拟机性能监控故障处理工具相关推荐
- java内存分配和垃圾回收_深入理解java虚拟机(二)垃圾收集器与内存分配策略...
垃圾收集器与内存分配策略 垃圾收集,三个步骤 什么时候收集,收集那些,怎么收集 1.收集那些 我们会将一些不使用的对象进行收集,进行回收内存空间,我们怎么知道呢 1.引用计数法 如果这个实例被其他地方 ...
- Java虚拟机(jvm)——垃圾收集器与内存分配策略
文章目录 判断对象的存活 引用和对象死亡 4 种引用 宣告对象死亡 回收方法区 垃圾回收算法 标记清除算法: 标记复制算法: 标记整理算法 分代收集算法: 增量收集算法 一些相关的概念: System ...
- 深入理解JVM读书笔记二: 垃圾收集器与内存分配策略
3.2对象已死吗? 3.2.1 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它的地方,计数器值+1:当引用失效,计数器值就减1;任何时候计数器为0,对象就不可能再被引用了. 它很难解决对象 ...
- 【深入理解Java虚拟机学习笔记】第三章 垃圾收集器与内存分配策略
最近想好好复习一下java虚拟机,我想通过深读 [理解Java虚拟机 jvm 高级特性与最佳实践] (作者 周志明) 并且通过写一些博客总结来将该书读薄读透,这里文章内容仅仅是个人阅读后简短总结,加强 ...
- 《深入理解JAVA虚拟机》学习日志----一、自动内存管理机制(2.垃圾收集器与内存分配策略)
二.垃圾收集器与内存分配策略 前言:讨论的区域集中在Java堆和方法区中,而其他几个区域的内存分配和回收都具备确定性,所以不需过多考虑回收 的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了. ...
- 读书笔记——Java虚拟机垃圾收集器与内存分配策略
本文章已授权微信公众号郭霖(guolin_blog)转载. 本文章讲解的内容是Java虚拟机垃圾收集器与内存分配策略. 概述 说起垃圾收集(Garbage Collection),也就是GC,大部分人 ...
- java虚拟机读书笔记 第三章 垃圾收集器和内存分配策略
java虚拟机读书笔记 第三章 垃圾收集器和内存分配策略 GC需要完成的三件事情:哪些内存需要回收.什么时候回收.如何回收 垃圾回收器在对堆进行回收前,首先要确定那些对象存活,哪些对象已经死去,判断的 ...
- java eden分配参数,JVM垃圾收集器与内存分配策略,
垃圾收集器与内存分配策略 对象存活判断 引用计数算法 给对象添加一个计数器,每有一个引用+1,当引用失效-1,若为0则不在被使用. 可达性分析算法 对象是否可到达GC roots 或者说GC root ...
- JVM2:垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 文章目录 垃圾收集器与内存分配策略 对象回收 引用计数算法 可达性分析算法 四种引用类型 生存与死亡 回收方法区 垃圾收集算法 标记清除法 复制算法 标记-整理算法 HotS ...
- 03-1 手敲八千字,认识垃圾收集器必须清楚的前置知识【垃圾收集器的内存分配策略】
03-1 50问!了解垃圾收集器必须清楚的前置知识--垃圾收集器的内存分配策略 author:陈镇坤27 创建时间:2021年12月27日01:58:45 字数:7932 文章目录 03-1 50问! ...
最新文章
- http://www.shanghaihaocong.com-WORDPRESS开发的企业主题站
- 最“燃”研究生!浙工大 64 岁研究生毕业,老师称其毕业论文写的最好
- 认真工作的原因以及方法
- 3.2.2 请求分页管理方式
- qt5 交叉编译webkit_基于QT平台的交叉编译环境搭建的架构分析
- 第一个Spark程序
- 【模板】EK求最大流、dinic求最大流
- 看完这篇还不懂 MySQL 主从复制,可以回家躺平了~
- Internet Explorer 9 新功能:固定并快速打开常用网站
- 费诺码设计matlab,费诺编码的matlab实现.doc
- 炫酷大屏demo_那些炫酷高端的可视化大屏,是如何开发出来的?
- 开启“互联网+”模式打造智能移动APP巡检系统
- HDUOJ_2567_寻梦
- 机器学习 | 台大林轩田机器学习基石课程笔记5 --- Training versus Testing
- aligned内存对齐
- 运行web项目提示异常:non-compatible bean definition of same name and class【com.xxx.xxx.XXX】
- 三、道阻且长之单例模式
- win10模拟器(win10模拟器无限蓝卡)
- strace命令用法详解
- 用户运营:5步学会用户留存数据分析