JVM系列(二) — Java垃圾收集介绍

Stella981
• 阅读 201

这篇文章主要从以下几个方面介绍垃圾收集的相关知识

  一、判断对象是否已死

  二、主流垃圾收集算法

  三、内存分配与回收策略

  本章节主要从以下几个思考点着手介绍垃圾回收的相关知识:哪些内存需要回收?什么时候回收?如何回收?这也是经典的学习一个知识点的3h方法:what? when? how?

上一个章节已经介绍jvm运行时数据区的内存分布,垃圾回收主要发生在堆这个区,也就是众多对象实例呆着的地方

一、如何判断对象已死?

  相信面试过高级java的工程师肯定遇到过面试官这样的问题:两个对象之间互相循环引用,如何回收?换句话说如何判断这两个对象已死?

  这里就引出了一个经典算法:引用计数法。是这样设计的:给对象添加一个引用计数器,每当这个对象被引用时,计数器值+1,引用失效时,计数值-1,任何时刻,计数为0

的对象就是不可能再被使用的对象

  回到上面的例子,它很难解决互相引用的对象这种情况,于是导致GC无法回收他们

  于是出现了另一个经典算法:可达性分析算法,基本思路是通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,

当一个对象到GC Roots没有任何引用链相连,或者称从GC Roots到这个对象不可达时,则证明这个对象是不可用的

  作为GC Roots的对象一般有以下几种:虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI引用的对象(这一种不太熟悉)

  关于java对引用的概念细分为强引用,软引用,弱引用,虚引用的细节,可以阅读该书了解,在此不再介绍

二、几种常见的垃圾收集算法

  1、Mark-Sweep

  标记-清除算法,分为标记,清除两个阶段,首先标记出所有需要回收的对象,标记完成后统一回收

  不足:效率不高;回收后产生大量不连续的内存碎片。碎片太多的话,需要分配大对象时,无法找到足够的连续内存而不得不提前触发新一轮的垃圾收集动作

  2、Copying

  复制算法,大多商业虚拟机都采用这种收集算法回收新生代,具体的在第三点内存分配会讲到

  3、Mark-Compact

  标记-整理算法。一般使用于老年代

  4、Generational Collection

  分代收集算法。当前商业虚拟机的垃圾收集都采用分代收集算法,一般是把Java堆分为新生代和老年代,根据各自特点采用最适当的收集算法。

三、内存分配与回收策略

  Java的自动内存管理机制可以归结为解决了两个问题:给对象分配内存以及回收分配给对象的内存。Java的内存分配策略并不是绝对的或者固定的,这取决于

当前使用的垃圾收集器组合,以及虚拟机中与内存分配相关的参数设置,接下来讲的是最为普遍的内存分配规则

  (1)对象优先在Eden区分配

  新生代区域一般被分为较大的Eden空间和两块较小的Survivor空间(通常称为From和To),HotSpot虚拟机默认Edon和两个Survivor的大小比例是8:1:1,

新创建的对象一般会在Edon和From中,当Edon区没有足够的空间进行分配时,将触发一次Minor GC,前面讲过大多数对象是朝生夕死的,因此Minor GC非常频繁

当一次Minor GC过后,仍然存活的对象会一次性复制到To区域中,然后清理掉Edon和From;这时候注意,From和To将交换角色,现在新的To是清理后的From

因此To区域总能保证每次Minor GC后留有一定的空间容纳尚存活的对象

  (2)长期存活的对象将进入老年代

  虚拟机给每个对象都定义了一个对象年龄(Age)计数器,在Edon出生的对象经过第一次Minor GC后仍然存活,并能在Survivor容纳的话Age将设为1,在Survivor区

每熬过一次Minor GC,Age+1,当Age达到设置的参数值-XX:MaxTenuringThreshold(默认值15),将晋升老年代,关于晋升老年代的条件并非一定要达到这种情况,

java虚拟机有动态对象年龄判定策略,具体可阅读本书3.6.4细节

  (3)大对象直接进入老年代

  所谓大对象指的是需要大量连续内存空间的对象,最典型的如很长的字符串以及数组,经常出现大对象意味着很可能内存中还有不少空间时就得提前触发垃圾收集

以获取足够的连续空间来安置他们。

  (4)触发Full GC的条件

  Full GC的速度一般比Minor GC慢10倍以上,触发一次Full GC经常会伴随一次Minor GC,一种触发条件为,一次Minor GC发生后将要晋升为老年代的对象大小超过

老年代现有剩余空间大小,这种情形不难想象。java的老年代空间分配担保细节可细读3.6.5节知晓,此处不再细说

最后上图一张作为结尾,一目了然:

JVM系列(二) — Java垃圾收集介绍

点赞
收藏
评论区
推荐文章
刚刚好 刚刚好
2个月前
css问题
1、 在IOS中图片不显示(给图片加了圆角或者img没有父级) <div<img src""/</div div {width: 20px; height: 20px; borderradius: 20px; overflow: h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
晴空闲云 晴空闲云
2个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。 盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
> MemFire Cloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
JVM系列之:内存与垃圾回收篇(二)
JVM系列之:内存与垃圾回收篇(二) ================== ##本篇内容概述: 1、堆Heap Area 2、方法区Method Area 3、运行时数据区总结 4、对象的实例化内存布局和访问定位 一、堆 Heap Area ------------- ### 1、堆的核心概念
Stella981 Stella981
1年前
JVM系列篇:7种JVM垃圾收集器特点,优劣势、及使用场景
**本系列会持续更新**。 ------------- ![](https://oscimg.oschina.net/oscnet/945dbe48630eb4284fea936b19161c0f08a.jpg) 今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。 **一、常见的垃圾收集器
Wesley13 Wesley13
1年前
Java虚拟机垃圾回收相关知识点全梳理(上)
一、前言 ---- 笔者最近在复习JVM的知识,本着记录分享的精神,整理下学习Java虚拟机垃圾回收相关知识点,由于整个垃圾回收内容比较多,我将整理成上下两篇文章去分享,上篇我会主要分享Java虚拟机的运行时数据区域划分,垃圾回收算法。下篇文章主要分享Java虚拟机的垃圾回收器以及一些虚拟机调优建议。 二、运行时数据区 -------- Java虚拟机
Stella981 Stella981
1年前
JVM垃圾回收器思维导图
JVM垃圾回收器思维导图,介绍了各种垃圾回收器概述,垃圾收集的算法及其特点,使用场景 ![](https://oscimg.oschina.net/oscnet/2580cd29-8631-4278-b730-349543a2bdbe.png) 思维导图下载文件:(包含上次java线程) 地址:https://pan.baidu.com/s/1nv
Stella981 Stella981
1年前
JavaScript性能优化
> ❝ > > 性能优化是一个很大的概念,性能优化的方向有很多比如底层、框架层面上、页面上等等,本篇文章介绍的是JavaScript语言的优化,了解JavaScript的运行的机制 > > ❞ 本片文章主要从如下几个方面讲解: * 内存管理 * 垃圾回收与常见GC算法 * V8引擎的垃圾回收 * Perf
Wesley13 Wesley13
1年前
java垃圾回收浅析
摘要 -- 垃圾回收和内存分配相关,先了解运行时数据区域的划分及各个区域的作用。 垃圾回收主要需要考虑的3个问题: 1、什么时候回收; 2、哪些对象需要回收; 3、如何回收。 运行时数据区域 ------- ![](http://static.oschina.net/uploads/img/201504/29004147_aU5w.png)
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
# Javascript ## 判断对象是否为空 ```js Object.keys(myObject).length === 0 ``` ## 经常使用的三元运算 > 我们经常遇到处理表格列状态字段如 `status` 的时候可以用到 ``` vue