首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JVM 《一 JVM 中的垃圾回收》

JVM 《一 JVM 中的垃圾回收》

作者头像
邹志全
发布于 2020-02-25 08:24:13
发布于 2020-02-25 08:24:13
47900
代码可运行
举报
文章被收录于专栏:EffectiveCodingEffectiveCoding
运行总次数:0
代码可运行

上一篇我们介绍了JVM,还有JVM中的内存结构。

当我们了解其中的内存之后,我们可能会有一点想法,我们的对象、相关类信息是存放在Java堆、方法区之中的。那我们的程序正在不断的new 对象、不断的loading Class。那么我们的JVM为什么没炸了(OOM),即使数量不会多到炸,但是我们不用的那些对象难道一直要仍在内存中?

cpp这样的语言,程序员是对自己的对象负责的,用完之后得了结了它。那Java呢?类似于以上的问题,是依靠JVM的垃圾回收机制去处理那些废弃的对象还有类信息的。

垃圾:废弃的对象、类信息、常量

回收:如何标记垃圾、如何清扫垃圾

垃圾的定义是比较巧妙的,JVM需要完完全全的确定我们不再使用了,才将其定义为垃圾。

《深入理解Java 虚拟机》一书中对什么是垃圾有一个有趣的标题— — 对象已死?

首先说 废弃的对象:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
      当一个对象,对我们来说是不可见、并且不可达的。那么如何判断 有这么两种方式或方法

1> 引用计数法:判断程序是否对这个对象还持有引用(这个对象是否还有使用的可能)

这个方法的优缺点显而易见,效率高,但是很有可能出现循环引用。

2>可达性分析:在说可达性之前,先说一个概念叫做GCRoot(既JVM 垃圾回收中判断对象是否可达的起点,是否仍被使用的起始节点),GCRoot常常有这么几个点:栈中所引用的对象(既被方法中直接使用的对象)、方法区中静态元素所引用的对象。

当我们有了GCRoot之后,我们便可以从它们出发去探索我们的对象了,那些不可达的也就可以被判断为应该不会被使用。也就一定程度上可以被标记待回收。

为了好理解,还是画个图吧

image.png

然后知道如何辨别和标记处垃圾之后,剩下的便是清理工作了。

JVM中的垃圾清扫或者收集算法有这么几种:标记-清除、标记-整理、复制、分代回收

标记-清除:

见明知义,先标记再清除(容易实现,但是效率较低、容易产生大量的内存碎片),放个图更好理解吧

image.png

针对内存碎片这个事儿,JVM也算是做出了不少策略。比如下面的,标记整理、复制

标记整理:

清扫掉废弃对象、并且整理,虽然没有内存碎片了,但是需要额外的整理工作,不仅需要标记存活的对象,还需要整理所有存活对象的引用地址。

放个图吧~

image.png

复制:其实是回收时将内存分为两部分,然后将存活的对象收集起来,清除掉待会收区域的垃圾就好啦。效率比标记整理要高,但是浪费了一部分空间。

image.png

JVM是可以这么玩复制算法的,新生代划分为三块区域(Eden区、2个Survival区,这其实就是种简单的面相程序员的一种抽象而已,具体低层实现比这个要复杂的多),其中默认Eden:Survival ==8:1,这个是要根据具体的对象的存活率来定的,为啥?别急,慢慢来。

首先新产生的对象是放在Eden中的,然后GC的时候是将存活对象取出来放到一个Survival(存活区)中,然后回收完成,继续向Eden中扔对象,下一次回收的时候是回收Eden及存放存活对象的那个Survival中,然后把这次的GC幸存者放在空的Survival中,然后回收完成,继续向Eden中扔对象,下一次回收的时候是回收Eden及存放存活对象的那个Survival中,然后把这次的GC幸存者放在空的Survival中(依次循环,我就不复制文字了,其中经历好多次的老对象到达年龄后是被请到老年区的。根据存活率控制空间比值是很重要哒,省的动不动向老年代抛对象)

image.png

然后是分代收集:就是按照对象年龄(经历的回收次数)作为主要标准,对Java Heap进行分区处理,之前作为简单例子说复制的时候提到过。

然后生命周期短的对象、生命周期长的对象,所采取的应该是不一样的,因为对象的存活率差太多。比如标记整理适合老年代,标记清除新生代也可以使用。这些在Java Heap 对象回收的时候其实是配合使用的。具体JVM使用哪种算法,其实是按照垃圾回收器来定的,感觉分代回收很高级的样子,其实在G1中已经弱化分代了。感觉标记-清除那么些毛病,为啥CMS使用它。每个具体的回收算法都有自己的优点和缺点,对这些算法进行合理的优化,相互配合在对象存活率不同的区域使用才能发挥更好的效果。具体的算法或者垃圾回收器的选择,要根据现实世界问题情形及相关物理硬件条件。

然后是对于废弃常量还有类的回收(方法区的回收)

就一点何为废弃的类:

1>该类所有的实例都已经被回收

2>加载该方法的ClassLoader已经被回收

3>该类对应的Class对象已无引用,并且无法通过反射访问。

但满足以上条件时,是允许进行回收的。

并且方法区也是会有溢出风险的,而且也会有废弃产生。所以也具有回收的意义,尤其是在大量反射使用的场景。

然后提几个中间没说到的东西:

1> Stop the world,在对象进行可达性分析的时候,会出现一次骤停(停止在使用对象的线程),然后标记线程启动,对对象进行标记。(并不是一下子让所有线程停止、而是让线程在安全点自行暂停)

2> finalize( ) ,这是每本书都不推荐使用的方法。它是在回收过程中自动执行的,并且仅执行一次。不同于cpp中的析构函数,这个不是来销毁对象的,据说是用来做一些对象销毁前必要的清理工作的。存在内存泄漏的风险。而且这个会让本来在回收流程中的对象复活(仅仅需要在方法中把对象的引用传给一个GCRoot可达的地方就好)。

3>Java 引用相关(传送门~)

4> 大对象直接进入老年代

下一篇 或者 后面几篇 说具体的垃圾回收器,以G1为主,CMS也会说一说。其他那些会大体提一提(较为简单,篇幅不大),然后是关于GC日志分析的。

具体怎么调优和选择,还有我们编码相关的注意事项会在调优那一篇章进行描述~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
jvm的垃圾回收算法_jvm垃圾回收策略
相比C语言,JVM虚拟机一个优势体现在对对象的垃圾回收上,JVM有一套完整的垃圾回收算法,可以对程序运行时产生的垃圾对象进行及时的回收,以便释放JVM相应区域的内存空间,确保程序稳定高效的运行,但在真正了解垃圾回收算法之前,有必要对JVM的对象的引用做一个简单的铺垫
全栈程序员站长
2022/10/01
8340
jvm的垃圾回收算法_jvm垃圾回收策略
JVM垃圾回收算法以及垃圾回收器机制
JVM中,程序计数器、虚拟机栈、本地方法栈都是都是线程私有的,随线程而生随线程而灭,栈帧(栈中的对象)随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理。
Java技术债务
2022/08/09
6610
JVM垃圾回收算法以及垃圾回收器机制
聊聊JVM中的垃圾回收(GC)
Java相对于C/C++语言来说,最明显的特点在于Java引入了自动垃圾回收。垃圾回收(Garbage Collection简称GC)可以使程序员不在需要关心JVM内存管理的问题,专注于写程序本身。平时程序员是很难感知到GC的存在,但是如果涉及到一些性能调优,线上的问题排查等等,深入地了解GC是必不可少的。往往通过一些JVM参数的设置能就使系统性能提高不少。
java技术爱好者
2021/01/06
6650
JVM垃圾回收机制
垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,那些已经“死去”。判断对象是否已“死”有如下几种算法:
落寞的鱼丶
2022/02/07
3310
深入JVM垃圾回收机制,值得你收藏
JVM可以说是为了Java开发人员屏蔽了很多复杂性,让Java开发的变的更加简单,让开发人员更加关注业务而不必关心底层技术细节,这些复杂性包括内存管理,垃圾回收,跨平台等,今天我们主要看看JVM的垃圾回收机制是怎么运行的,希望能够帮到大家,
阿伟
2020/02/26
6480
深入理解JVM的垃圾回收机制
上一篇博客介绍了Java运行时内存的各个区域。对于程序计数器、虚拟机栈、本地方法栈这三个部分而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者线程结束时,内存就自然跟着线程回收了。因此本篇文章所讲的有关内存分配和回收关注的是Java堆与方法区这两个区域。
全栈程序员站长
2022/08/11
3980
深入理解JVM的垃圾回收机制
jvm的垃圾回收机制_垃圾回收厂
我们知道自动的垃圾回收机制是Java语言一个特点,它让我们在写程序的时候不再需要考虑内存管理问题。内存管理实际上就是分配内存和回收内存这两个问题,在上一篇文章我大概介绍了jvm是如何划分内存空间以合理的分配内存的,而这篇文章就介绍一下jvm是如何回收内存的。
全栈程序员站长
2022/09/23
5980
jvm的垃圾回收机制_垃圾回收厂
JVM垃圾回收算法
分为标记和清除两个阶段,首先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象
终有链响
2024/07/29
1470
JVM垃圾回收算法
JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)
  按照套路是要先装装X,谈谈JVM垃圾回收的前世今生的。说起垃圾回收(GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史比Java久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术。设计和优化C++这门语言的专家们要长点心啦~~
哲洛不闹
2019/03/11
1.6K0
JVM的垃圾回收机制 总结(垃圾收集、回收算法、垃圾回收器)
JVM又曾放过谁,垃圾终将被回收!
在Java中有一个很重要的概念,即一切皆对象。所谓对象,就是将现实中的事物抽象出来,进而可以通过继承、实现和组合的方式把万事万物都给容纳,所以理解对象的概念在学习Java(包括所有的面向对象的语言)的过程中至关重要。
Simon郎
2021/02/23
5551
jvm垃圾回收详解_java 垃圾回收器
JVM 会自动帮程序员进行垃圾回收,并不需要程序员手动的进行垃圾回收(C++等语言需要自己手动回收垃圾),了解 JVM 的垃圾回收,可以帮程序员写出占用内存更小、更高效的程序。
全栈程序员站长
2022/10/01
1.2K0
jvm垃圾回收详解_java 垃圾回收器
JVM的垃圾收集器策略
程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
大大大大大先生
2018/09/04
3520
(4)JVM——垃圾回收算法
介绍:在程序运行过程中,程序计数器、虚拟机栈、本地方法栈 3 个区域随线程而生,随线程而灭,不用我们关注内存的回收。而 Java 堆和方法区不一样,此处的内存使用和回收是动态的,其中讲垃圾回收主要是在 Java 堆。
凡人飞
2020/09/20
3910
JVM常见面试题(四):垃圾回收
当需要排查各种内存溢出问题、当垃圾收集成为系统达到更高并发的瓶颈时,我们就需要对这些“自动化"的技术实施必要的监控和调节。
寻求出路的程序媛
2024/11/24
2880
JVM常见面试题(四):垃圾回收
深入理解JVM - 垃圾回收算法
这一期讲述垃圾回收的算法。我们根据分代的理念讲述一下JVM是使用什么算法对于不同分代的对象进行垃圾回收的的,同样内容十分基础,但是对于学习JVM后续的内容十分重要。
阿东
2021/08/16
1.9K0
深入理解JVM - 垃圾回收算法
详细捋一捋JVM的垃圾回收机制
在日常工作或面试当中,经常会遇到JVM的垃圾回收问题,今天就来详细捋一捋相关的知识点。
田维常
2020/04/14
4200
详细捋一捋JVM的垃圾回收机制
JVM垃圾回收机制
标记复制 将可用内存按容量划分为大小相等的两块,每次使用其中的一块,这一块用完了就将还存活者的对象复制到另一块上面 (新生代)
是阿超
2021/12/30
2820
GC 垃圾回收
我们知道Java是一门面向对象的语言,在一个系统运行中,会伴随着很多对象的创建,而这些对象一旦创建了就占据了一定的内存,在上一篇中,我们介绍过创建的对象是保存在堆中的,当对象使用完毕之后,不对其进行清理,那么会一直占据内存空间,很明显内存空间是有限的,如果不回收这些无用的对象占据的内存,那么新创建的对象申请不了内存空间,系统就会抛出异常而无法运行,所以必须要经常进行内存的回收,也就是垃圾收集。
栗筝i
2022/12/01
2970
GC 垃圾回收
探究JVM——垃圾回收
垃圾回收主要考虑三件事情:哪些内存需要回收?什么时候回收?如何回收? 一、哪些内存需要回收? 堆内存:对于JVM 来说,垃圾回收主要是针对堆内存中的对象实例。 方法区:垃圾收集行为在方法区是比较少出现的,一般来说,这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是必要的。 二、什么时候回收?   在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(即不可能再被任何途径使
欠扁的小篮子
2018/04/11
6590
探究JVM——垃圾回收
八股文之【JVM垃圾回收】
上面提到的标记的算法,怎么标记一个对象是否存活?简单的通过引用计数法,给对象设置一个引用计数器,每当有一个地方引用他,就给计数器+1,反之则计数器-1,但是这个简单的算法无法解决循环引用的问题。
崩天的勾玉
2021/12/20
1K0
八股文之【JVM垃圾回收】
相关推荐
jvm的垃圾回收算法_jvm垃圾回收策略
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验