总结JVM垃圾回收

目录

一.什么是垃圾回收(GC)

二.为什么会有垃圾回收

三.垃圾回收主要回收哪个内存区域?

四.标记的过程

五.回收的过程 


一.什么是垃圾回收(GC)

  • JVM(Java虚拟机)的垃圾回收是指自动管理内存分配和释放的过程。在Java程序中,当对象不再被引用或者不可达时,垃圾回收器会自动识别并回收这些对象所占用的内存空间,使其能够被再次使用。
  • 垃圾回收的主要目标是通过释放不再使用的对象所占用的内存,以最大化可用内存空间,减少内存泄漏和程序崩溃的可能性。垃圾回收器会周期性地运行,自动检测和回收不再使用的对象。
  • 在垃圾回收的过程中,垃圾回收器会首先标记出所有的存活对象,然后清理掉那些没有被标记的对象。为了实现垃圾回收,JVM使用了不同的垃圾回收算法,包括标记-清除算法、复制算法、标记-整理算法等。
  • 垃圾回收的好处是可以简化内存管理,节省开发人员手动释放内存的工作。然而,垃圾回收也可能引起一定的性能开销,因为垃圾回收过程会占用CPU时间。
  • 总的来说,JVM的垃圾回收是一种自动管理内存的机制,使得开发人员可以更专注于业务逻辑,而不必过多考虑内存管理的细节。

二.为什么会有垃圾回收

在c语言中,malloc的内存必须手动free,否则就容易出现内存泄漏, 这个后果对于程序员来说不仅会扣工资还会加班,这无疑是巨大的打击.java等后续的编程语言都引入了 垃圾回收 来解决上述的问题.它能够有效的减少内存泄漏的出现概率!

三.垃圾回收主要回收哪个内存区域?

 堆 (new 出来的对象) 

 程序计数器,就是一个单纯存地址的整数,不需要回收,它会随着线程一起销毁

 栈,也是随着线程一起销毁,方法调用完,方法的局部变量自然随着出栈操作就销毁了

 元数据区 /方法区 ,存的类对象,很少会"卸载"

 因此,堆是GC的主要目标 ,那么GC也就是以 对象 为单位进行释放的.


 GC中主要有两个过程:

1.标记的过程:主要是找谁是垃圾

2.回收的过程:把垃圾对象的内存给释放掉


四.标记的过程

 一个对象,如果后续再也不用了,就可以认为是垃圾,在java中使用一个对象,只能通过引用,此时这个对象没有引用指向它,那这个对象一定是无法被使用的,这个对象就是妥妥的垃圾.那如果一个对象已经不想用了,但是这个引用可能还指向它,那这个对象不会当成垃圾,java中只是单纯通过引用没有指向这个操作来判定垃圾的,这个判定是比较保守的,也是最大程度避免"错杀".释放不及时是小事,误杀是大事.


java怎样知道一个对象是否有引用指向呢?

答:采用可达性分析: 把对象之间的引用关系,理解成了一个树形结构,从一些特殊的起点出发,进行遍历.只要能遍历访问到的对象,就是"可达",再把"不可达的"当做垃圾丢掉即可.


此算法的核心思想为 : 通过一系列称为 "GC Roots" 的对象作为起始点,从这些节点开始向下搜索,搜索 走过的路径称之为" 引用链 " ,当一个对象到 GC Roots 没有任何的引用链相连时 ( GC Roots 到这个对象 不可达) 时,证明此对象是不可用的。以下图为例:
对象 Object5-Object7 之间虽然彼此还有关联,但是它们到 GC Roots 是不可达的,因此他们会被判定为 可回收对象。

 可达性分析,就是从所有的 gcroots的起点出发,看看该对象里又通过引用能访问哪些对象,顺藤摸瓜,把所有可以访问的对象都给遍历一遍(遍历的同时把对象标记成"可达"),剩下的自然就是不可达的,就可以当成垃圾回收掉了.

可达分析需要有起点 gcroots:

  1. 栈上的每个局部变量
  2. 常量池中引用的对象
  3. 方法区中,静态成员引用的对象

优点:不浪费内存空间

缺点:消耗更多的时间,因此某个对象成立垃圾,不一定第一时间发现,因为扫描的过程,需要时间

在进行可达性分析的时候,要顺藤摸瓜,一旦这个过程中,当前的代码中的对象引用关系发生了变化,那就麻烦了,因此,为了更准确的完成这个"摸瓜"的过程,需要让其他的业务线程暂停工作(STW--stop the work)STW是个诟病的问题,Java\发展这么多年,垃圾回收不断的更新,STW问题已经优化了,不能完全消除,但是已经很好了.

五.回收的过程 

 三种典型的策略:

 1.标记清除: 直接把垃圾对象的内存释放了(图中黑的区域).

 缺点: 这种方式会产生内存碎片,因为申请空间都是申请的"整块的连续的空间",现在这里空闲的空间都是离散的,独立的空间.


2.复制算法:把整个内存空间,分成两段,一次只用一半,图中是2,4,6为垃圾,把1,3,6拷贝到右边,然后把左边一整块全删除了. 

 优点:解决了 "标记整理 "中的内存碎片问题

 缺点:1.内存利用率比较低 .

          2.如果当前的对象大部分都是保留的,垃圾很少,此时复制成本就比较高


3.标记整理:类似于顺序表删除中间元素,有一个搬运的过程,把有用的元素往前搬运,这样后面的就都是垃圾了,然后一块删除.

 

 优点:1.可以解决内存碎片问题 ,2.内存利用率也高

  缺点:搬运的开销也是比较大的.


上面的各有优缺点,因此,JVM的实现思路,是结合上述几种思想,分代回收思想:针对不同的情况,使用不同的策略,取长补短.当前 JVM 垃圾收集都采用的是"分代收集(Generational Collection)"算法,这个算法并没有新思想,只是根据对象存活周期的不同将内存划分为几块.一般是把Java堆分为新生代和老年代。在新生代中,每次垃圾回收都有大批对象死去,只有少量存活,因此我们采用复制算法;而老年代中对象存活率高、没 有额外空间对它进行分配担保,就必须采用"标记-清理"或者"标记-整理"算法

新生代:一般创建的对象都会进入新时代;

老年代:大对象和经历了N次(一般情况默认是 15 次)垃圾回收依然存活下来的对象会从新生代移动到老年代;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值