young gc频繁_由浅入深了解GC原理

垃圾收集(GC)是Java中的一个重要机制,它自动管理内存,避免程序员手动释放。本文介绍了GC的基本概念、常用算法(如标记-清除、标记-压缩、复制和分代收集)以及垃圾收集器,如串行、并行和并发收集器。讨论了如何判断对象存活(引用计数和可达性分析),以及finalize()方法的作用和问题。最后,提供了优化GC的建议,如尽早释放引用、避免使用finalize()和关注集合类型对GC的影响。
摘要由CSDN通过智能技术生成

GCGarbage Collection)很大程度上帮助Java程序员解决了内存释放的问题,有了GC,就不需要再手动的去控制内存的释放。

在阅读之前需要了解的相关概念:

Java 堆内存分为新生代和老年代,新生代中又分为 1Eden 区域 和 2Survivor 区域。

什么是GC(Garbage Collection)

GC垃圾收集,Java提供的GC可以自动监测对象是否超过作用域从而达到自动回收内存的目的。

每个程序员都遇到过内存溢出的情况,程序运行时,内存空间是有限的,那么如何及时的把不再使用的对象清除将内存释放出来,这就是GC要做的事。

需要GC的内存区域

JVM 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 JAVA 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的。

注意:
对于 Java8HotSpots 取消了永久代,那么是不是也就没有方法区了呢?当然不是,方法区是一个规范,规范没变,它就一直在。那么取代永久代的就是元空间。它可永久代有什么不同的?存储位置不同,永久代物理是是堆的一部分,和新生代,老年代地址是连续的,而元空间属于本地内存;存储内容不同,元空间存储类的元信息,静态变量和常量池等并入堆中。相当于永久代的数据被分到了堆和元空间中。

GC的对象

当一个对象到GC Roots不可达时,在下一个垃圾回收周期中尝试回收该对象,如果对象重写了finalize(),并在这个方法中成功自救(将自身赋予某个引用),那么这个对象不会被回收。但如果这个对象没有重写finalize()方法或已执行过这个方法,该对象将会被回收。

需要进行回收的对象就是已经没有存活的对象,判断一个对象是否存活常用的有两种办法:引用计数算法和可达性分析算法。

  • 引用计数算法:
    每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
  • 可达性分析算法(Reachability Analysis):
    GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。
在Java语言中, GC Roots包括:
+ 虚拟机栈中引用的对象;
+ 方法区中类静态属性实体引用的对象;
+ 方法区中常量引用的对象;
+ 本地方法栈中 JNI引用的对象。

什么时候触发GC

  • 程序调用System.gc时,但不是必然执行
  • 系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)
GC又分为 Minor GCFull GC (也称为 Major GC) Minor GC触发条件:当 Eden区满时,触发 Minor GCFull GC触发条件:
+ 调用 System.gc时,系统建议执行 Full GC,但是不必然执行
+ 老年代空间不足
+ 方法去空间不足
+ 通过 Minor GC后进入老年代的平均大小大于老年代的可用内存
+ 由 Eden区、 From Space区向 To Space区复制时,对象大小大于 To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

GC做了什么事

主要做了清理对象,整理内存的工作。Java堆分为新生代和老年代,采用了不同的回收方式。

GC常用算法

GC常用算法有:标记-清除算法,标记-压缩算法,复制算法,分代收集算法

目前主流的JVMHotSpot)采用的是分代收集算法。

标记-清除算法(Mark-Sweep)

首先标记出所有需要回收的对象,标记完成后回收所有被标记的对象。不足主要体现在效率和空间,从效率的角度讲,标记和清除效率都不高;从空间的角度讲,标记清除后会产生大量不连续的内存碎片, 内存碎片太多可能会导致需要分配较大对象时,无法找到足够的连续内存而提前触发一次垃圾收集动作。

从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象,如果活着,就标记。只有全部标记完毕的时候,清理动作才开始。在清理的时候,没有标记的对象将会被释放,不会发生任何动作。但是剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间的话,就得重新整理剩下的对象。

优点:标记—清除算法中每个活着的对象的引用只需要找到一个即可,找到一个就可以判断它为活的。此外,更重要的是,这个算法并不移动对象的位置。

缺点:它的缺点就是效率比较低(递归与全堆对象遍历)。每个活着的对象都要在标记阶段遍

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值