Java基础 GC机制

知识准备:Java 堆内存分为新生代和老年代,新生代中又分为1个 Eden 区域 和 2个 Survivor 区域(from、to)。

一、什么是GC:如何及时的把不再使用的对象清除将内存释放出来。

理解GC机制就从:“GC的区域在哪里”,“GC的对象是什么”,“GC的时机是什么”,“GC做了哪些事”几方面来分析。

(1)GC的区域在哪里

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

2、GC的对象

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

(1)引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。

(2)可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。

在Java语言中,GC Roots包括:

虚拟机栈中引用的对象。

方法区中类静态属性实体引用的对象。

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

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

3、什么时候触发GC

(1)程序调用System.gc时可以触发

(2)系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)

GC又分为 minor GC 和 Full GC (也称为 Major GC )

Minor GC触发条件:当Eden区满时,触发Minor GC。

Full GC触发条件:

  a.调用System.gc时,系统建议执行Full GC,但是不必然执行

  b.老年代空间不足

  c.方法区空间不足

  d.通过Minor GC后进入老年代的平均大小大于老年代的可用内存

  e.由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

4、GC做了什么事

 主要做了清理对象,整理内存的工作。Java堆分为新生代和老年代,采用了不同的回收方式。(回收方式即回收算法详见后文)

二、GC常用算法

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

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

此处主要介绍分代收集算法:

现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代(Young)和老年代(Tenure)。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记-整理 或者 标记-清除。

具体过程:新生代(Young)分为Eden区,From区与To区

当系统创建一个对象的时候,总是在Eden区操作,当这个区满了,那么就会触发一次YoungGC,也就是年轻代的垃圾回收。一般来说这时候不是所有的对象都没用了,所以就会把还能用的对象复制到From区。 

再下一次YoungGC的时候,则是将Eden区与To区中的还在被使用的对象复制到From区

经过若干次YoungGC后,有些对象在From与To之间来回游荡,这时候From区与To区亮出了底线(阈值),这些家伙要是到现在还没挂掉,对不起,一起滚到(复制)老年代吧。

老年代经过这么几次折腾,也就扛不住了(空间被用完),好,那就来次集体大扫除(Full GC),也就是全量回收。如果Full GC使用太频繁的话,无疑会对系统性能产生很大的影响。所以要合理设置年轻代与老年代的大小,尽量减少Full GC的操作。

 

参考:https://www.cnblogs.com/jobbible/p/9800222.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于2023年的Java高级面试题,以下是一些可能涉及的主题和问题: 1. Java基础知识 - 什么是Java的反射机制?如何使用反射调用方法和访问属性? - 什么是Java的序列化? 如何实现对象的序列化和反序列化? - 解释一下Java中的多态性和继承关系。 - 什么是内部类?它们有哪些不同类型? - 什么是异常处理?Java中常见的异常类型有哪些? 2. 集合框架 - 介绍一下Java的集合框架,并举例说明各种集合类的使用场景。 - ArrayList和LinkedList之间的区别是什么? - HashMap和TreeMap之间的区别是什么? - 什么是迭代器?如何使用迭代器遍历集合元素? 3. 多线程与并发 - 什么是线程安全?如何在Java中实现线程安全? - 解释一下Java中的线程池,它有哪些优势? - 什么是死锁?如何避免死锁的发生? - 介绍一下Java中的同步机制,包括synchronized关键字和Lock接口。 4. 设计模式 - 介绍一下常见的设计模式,如单例模式、工厂模式、观察者模式等。 - 解释一下策略模式和模板方法模式的区别。 - 什么是依赖注入(DI)?如何在Java中实现依赖注入? 5. JVM与性能优化 - 什么是Java虚拟机(JVM)?它有哪些重要组成部分? - 什么是垃圾回收(GC)?Java中有哪些常见的垃圾回收算法? - 如何进行Java程序的性能调优? - 什么是内存泄漏?如何避免内存泄漏的发生? 这些问题只是作为参考,并不代表完整的面试题目。实际面试中,可能还会涉及到项目经验、数据库、网络编程等其他方面的问题。建议在准备面试时全面复习Java的各个方面知识,并结合自己的项目经验进行准备。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值