JVM 调优系列之图解垃圾回收

转载自  JVM 调优系列之图解垃圾回收

摘要: jvm必知系列,总结一些常见jvm回收机制,方便查阅


从这篇开始我们开始探讨一些jvm调优的问题。在jvm调优中一个离不开的重点是垃圾回收,当垃圾回收成为系统达到更高并发量的瓶颈时,我们就需要对jvm中如果进行“自动化”垃圾回收技术实施必要的监控和调节。


对于调优之前,我们必须要了解其运行原理,java 的垃圾收集Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。因此本篇主要从这三个方面来了解:


1. 哪些对象需要被回收?

2. 什么时候回收?

3. 如何回收?


谁要被回收


java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同是数据区域,这些区域有各自各自的用途。主要包含以下几个部分组成:



程序计数器

程序计数器占用的内存空间我们可以忽略不计,它是每个线程所执行的字节码的行号指示器。


虚拟机栈

java的虚拟机栈是线程私有的,生命周期和线程相同。它描述的是方法执行的内存模型。同时用于存储局部变量、操作数栈、动态链接、方法出口等。


本地方法栈

本地方法栈,类似虚拟机栈,它调用的是是native方法。


堆是jvm中管理内存中最大一块。它是被共享,存放对象实例。也被称为“gc堆”。垃圾回收的主要管理区域


方法区

方法区也是共享的内存区域。它主要存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(jit)编译后的代码数据。


以上就是jvm在运行时期主要的内存组成,我们看到常见的内存使用不但存在于堆中,还会存在于其他区域,虽然堆的管理对程序的管理至关重要,但我们不能只局限于这一个区域,特别是当出现内存泄露的时候,我们除了要排查堆内存的情况,还得考虑虚拟机栈的以及方法区域的情况。


知道了要对谁以及那些区域进行内存管理,我还需要知道什么时候对这些区域进行垃圾回收。


什么时候回收


在垃圾回收之前,我们必须确定的一件事就是对象是否存活?这就牵扯到了判断对象是否存活的算法了。


引用计数算法

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器+1,当引用失效,计数器-1.任何时刻计数器为0的对象就是不可能再被使用的。


优点:实现简单,判定效率高效,被actionscript3和python中广泛应用。

缺点:无法解决对象之间的相互引用问题。java没有采纳


可达性分析算法

通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GCRoots没有任何引用链相连的时候,则证明此对象是不可用的。


比如如下,右侧的对象是到GCRoot时不可达的,可以判定为可回收对象。



在java中,可以作为GCRoot的对象包括以下几种:


* 虚拟机栈中引用的对象。

* 方法区中静态属性引用的对象。

* 方法区中常量引用的对象。

* 本地方法中JNI引用的对象。


基于以上,我们可以知道,当当前对象到GCRoot中不可达时候,即会满足被垃圾回收的可能。


那么是不是这些对象就非死不可,也不一定,此时只能宣判它们存在于一种“缓刑”的阶段,要真正的宣告一个对象死亡。至少要经历两次标记:


第一次:对象可达性分析之后,发现没有与GCRoots相连接,此时会被第一次标记并筛选。

第二次:对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,此时会被认定为没必要执行。


如何回收


上述的两点讲解之后,我们大概明白了,哪些对象会被回收,以及回收的依据是什么,但回收的这个工作实现起来并不简单。


首先它需要扫描所有的对象,鉴别谁能够被回收,其次在扫描期间需要 ”stop the world“ 对象能被冻结,不然你刚扫描,他的引用信息有变化,你就等于白做了。


分代回收

我们从一个object1来说明其在分代垃圾回收算法中的回收轨迹。


1、object1新建,出生于新生代的Eden区域。



2、minor GC,object1 还存活,移动到Fromsuvivor空间,此时还在新生代。



3、minor GC,object1 仍然存活,此时会通过复制算法,将object1移动到ToSuv区域,此时object1的年龄age+1。



4、minor GC,object1 仍然存活,此时survivor中和object1同龄的对象并没有达到survivor的一半,所以此时通过复制算法,将fromSuv和Tosuv 区域进行互换,存活的对象被移动到了Tosuv。



5、minor GC,object1 仍然存活,此时survivor中和object1同龄的对象已经达到survivor的一半以上(toSuv的区域已经满了),object1被移动到了老年代区域。



6、object1存活一段时间后,发现此时object1不可达GcRoots,而且此时老年代空间比率已经超过了阈值,触发了majorGC(也可以认为是fullGC,但具体需要垃圾收集器来联系),此时object1被回收了。fullGC会触发 stop the world。



在以上的新生代中,我们有提到对象的age,对象存活于survivor状态下,不会立即晋升为老生代对象,以避免给老生代造成过大的影响,它们必须要满足以下条件才可以晋升:


1、minor gc 之后,存活于survivor 区域的对象的age会+1,当超过(默认)15的时候,转移到老年代。

2、动态对象,如果survivor空间中相同年龄所有的对象大小的综合和大于survivor空间的一半,年级大于或等于该年级的对象就可以直接进入老年代。


以上采用分代垃圾收集的思想,对一个对象从存活到死亡所经历的历程。期间,在新生代的时刻,会用到复制算法,在老年代时,有可能会用到标记-清楚算法(mark-sweep)算法或者标记-整理算法,这些都是垃圾回收算法基于不同区域的实现,我们看下这几种回收算法的实现原理。


垃圾回收算法


标记清除法(Mark-Sweep)

标记清除法是垃圾回收算法的思想基础。标记清除算法将垃圾分为两个阶段:标记阶段和清除阶段。


标记阶段,通过根节点,标记所有从根节点开始的可达对象,未标记过的对象就是未被引用的垃圾对象。


清除阶段,清除所有未被标记的对象。



复制算法(Copying)

复制算法是,将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在适用的内存中存活对象复制到未使用的内存块,然后清除使用的内存块中所有的对象。



标记压缩算法(Mark-Compact)



标记压缩算法是一种老年代的回收算法。


标记阶段和标记清除算法一致,对可达对象做一次标记。


清理阶段,为了避免内存碎片产生,将所有的存活对象压缩到内存的一端。


垃圾收集器


垃圾收集器是内存回收的具体实现,不同的厂商提供的垃圾收集器有很大的差别,一般的垃圾收集器都会作用于不同的分代,需要搭配使用。以下是各种垃圾收集器的组合方式:




各种组合的优缺点:



以上优缺点来自:http://www.importnew.com/23752.html


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA注解和反射(笔记)

注解简介 Annotation是从JDK5.0开始引入的新技术). Annotation的作用 : 不是程序本身(可以对程序作出解释.(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取. Annotation的格式: 注解是以"注释名"在代码中存在的, 还可以添加一些参数值,例如:S…

车提示检测轮胎气压_水淹车估价中心_辽宁中车检

首页 > 新闻中心发布时间:2021-01-02 00:57:13 导读:辽宁中车检为您提供水淹车估价中心的相关知识与详情:在行车过程中,汽车受到振动,可能会引起前照灯部件的安装位置发生变动,从而改变光束的正确照射方向.同时,灯泡在使用过程中会逐步老化…

.NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

0x00 为什么需要Map(MapWhen)扩展 如果业务逻辑比较简单的话,一条主管道就够了,确实用不到Map。不过当业务逻辑比较复杂的时候,有时候我们可能希望根据情况的不同使用特殊的一组中间件来处理HttpContext。这种情况下如…

2小时学习Spring Boot 2019版本 代码一样推送至github上面去

简介:《2小时学习Spring Boot》后续进阶课程,主要讲述了Spring Boot针对Web方面的相关技巧 讲师实战课程《Spring Boot微信点餐系统》 http://coding.imooc.com/class/117.html 《Spring Cloud微服务实战》 http://coding.imooc.com/class/187.html 均已…

认识JVM--第一篇-对象分配&回收算法

转载自 认识JVM--第一篇-对象分配&回收算法本来标题党想写成《深入JVM》,不过不太敢写,我想一小篇博客我想还不足以说明JVM,在本文中,会就我所知给大家介绍JVM的很多内部知识,概念会相对较粗,因为太细…

JAVASE阶段流程图

转载于https://blog.csdn.net/czc514/article/details/106057366

hibernate配置详情3(Dept)

package org.hibernate_one.entity;import java.io.Serializable;/** 部门实体类* 符合javabean规范* 1.公共类* 2.具有公共的无参的构造方法* 3.私有属性* 4.getter setter方法* 5.实现序列化接口Serializable java.io*/public class Dept implements Serializable {//部门编…

学生上课睡觉班主任怎么处理_【师问师答】学生上课说话,点名批评还嘴怎么办?...

案例我是一个初二的英语老师,昨天上课一男生一直在说话。我点了他名字之后毫不畏惧,仍然接着说话。后来我让他站起来,他说他腰痛不能站。又继续和同桌说话,我火大啊,让他站出去说完了再进来。他就在座位上嘀嘀咕咕&…

.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件。除了直接用ApplicationBuilder的Use()方法注册中间件外,还可以使用ApplicationBuilder的扩展方法UseMiddleware()注册中间件。这种情况下可以注册类型&a…

Spring Boot进阶之Web进阶 代码推送的github上面去

还是搜狗的输入法比较好 Exception.class 上面开不见的部分是这里的 代码上次github上面去保存起来 https://github.com/yangjiabinylg/girl2 https://github.com/yangjiabinylg/girl2 全部做完了 代码提交到github 上面去了

JVM初探- 使用堆外内存减少Full GC

转载自 JVM初探- 使用堆外内存减少Full GC问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao、LinkedIn、Vdian), 虽然CMS可与用户线程并发GC以降低STW时间, 但它也并非十分完美, 尤其是当出现Concurrent Mode Failure由并行GC转入串行时, 将导致非常长时间的…

快捷生成---QQ点击联系我的方法

第一步 第二步 第三步 把uin2764954910 p2:2764954910:53 换成自己的QQ号 运行 完结撒花

.NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理、会话管理、路由等。所以搞明白中间件是如何注册并最终构建成管道的很重要。园子里很多先驱早已经开始了这方面的研究学习,也写了很多…

语言 高速公路超速处罚_重磅!全国高速将统一限速,这4种超速不再扣分罚款!【饮茶论道】...

在高速开车,经常会经历“断崖式降速”和“忽高忽低式限速”。相信不少吃了罚单的司机感受都是:哑巴吃黄连——有苦说不出……现在,重磅消息来啦!在高速公路上行驶前方没有任何障碍导航却突然提醒你“当前道路限速60km/h&#xff0…

SpringBoot开发常用技术整合 代码上传至github上面去

简介:本课程通过详细的对springboot的各个技能点逐一介绍与演示,可以很迅速的熟悉整个springboot框架体系,并且与springmvc有效的进行对比,理解异同,这样对于后续的springboot开发会非常迅速。同时课程中会针对不同的技…

Java中对象的三种状态

转载自 Java中对象的三种状态Java中的对象的三种状态是和垃圾回收紧密相关的,因此有必要深究。 状态一:可触及态:从根节点开始,可以搜索到这个对象,也就是可以访问到这个对象,也有人将其称为可达状态。 状…

HTML5(笔记)

什么是HTML Hyper Text Markup Language(超文本标记语言) 超文本包括:文字,图片,音频,视频,动画等 w3c标准 WOrld Wide Web Consortium(万维网联盟) 成立于1994年,Web技术领域最权威和具影响力的国际中…

训练测试数据大小不一致_三步学会训练狗狗不随地大小便

训练狗狗在规定的地点大小便是非常重要的训练,它决定了你的屋子和院子能否干净整洁。如果是室内训练,我要先告诉你一些相关的训练禁忌。首先,当狗狗在家里排便之后才对狗狗做出惩罚,是最普遍的一个训练错误,这只会使问…

使用实体框架、Dapper和Chain的仓储模式实现策略

关键要点: Dapper这类微ORM(Micro-ORM)虽然提供了最好的性能,但也需要去做最多的工作。在无需复杂对象图时,Chain这类Fluent ORM更易于使用。对实体框架(Entity Framework)做大量的工作后&#…

JVM-对象的存活与死亡

转载自 JVM-对象的存活与死亡 当Java虚拟机进行垃圾收集的时候,那么它必须要先判断对象,是否还存活,如果存活就不能对它进行回收。所以判断一个对象是否存活是Java虚拟机必须要实现的。1.对象是否存活  1)引用计数器&#xff1…