jvm GC

java内存模型主要分为线程私有的:jvm虚拟栈(栈帧), 本地方法栈,程序计数器
以及堆,方法区(runtime constant poll)。
线程中的内存随着线程结束而被回收,不需要考虑
但是堆和方法区需要gc回收,堆中存着基本所有对象实例。
如Object obj = new Object()此类所有new出来的东西,他们都在堆中。
哪怕值相同可是地址也是不同的,所以对于new的对象判断==是一定false的。
那么首先有这样的概念。
新生代,老年代, 永久代(在hotspot vm中的概念)。
以及
标记/清除算法, 标记/整理算法, 复制算法。

首先介绍标记/清除算法。
我们了解一个概念叫做GC roots.GC roots是一组活跃着的引用
也许是当前栈帧中指向堆中的引用,也许是当前正在调用的方法的类型参数,局部变量等…
我们通过GC roots 去遍历引用链,能够遍历到的对象我们就标记下来。
一遍遍历完了,我们将那些没有标记的,全部清除掉,那些就是GC回收的内存。
如 ABCDEFG 这一排连续的内存,假设A C E是没有被标记的。那么清除ACE
此时内存会变成这样 B D FG。
这个算法的缺点在于:1.全部遍历太耗时,如果被标记的是100%,那么无需清除,这样的代价是很大的,因为在进行GC时,会进入一个stop the world的状态,所有的程序是停止的,为什么这样做,因为如果在运行时,引用是会不停变化的,这样我们无法通过引用链去遍历对象,无法清除正确的垃圾。
所以如果在全部遍历而回收甚少的时候,是很亏的。
2.内存不连续,如果我们new了一个大的对象,需要用到一片连续的内存,那么这一片内存就无法使用了。

针对这两个缺点,出现了复制算法。
复制算法是将内存分成两半,先遍历一半之后,将清除完的这一片内存,复制到另一半空的内存中。注意这里复制过去后,不再是断断续续的内存了,而是一片连在一起的完整内存。

这个算法同样具有缺点。一个是内存分半的代价,一个是复制的代价。
内存分半意味着要减少一半的内存使用率,复制同样需要花费代价。

最后的标记整理算法,与清除算法区别不大,在进行回收以后,会根据某一段,将之后的内存全部并拢到一边,于是不再出现内存不连续的情况。

那么介绍新生代和老年代。

新生代使用复制算法,因为新生代“朝生夕死”, 死亡率高达98%。在JVM中我们的复制算法不再是用1:1一半的比例分配,而是8:1:1。
8:eden 1:from survivor 1: to survivor
首先使用eden和from。
再一次清除以后eden中仍然存活的对象被移到to区。此时eden应该为空了,而from中如果age超过阈值(好像为15,每一次回收为一轮)的对象会被移到old gen,老年代中。然后留下来的会被移到to里面。接着to会被该做from,而以前的from会被改为to,在每一轮回收以后to都应当是空的。
为什么这里使用复制算法,我们前面提及如果标记的是100%那么就是做了一次无用的遍历,可是新生代死亡率高达98%那么清除掉98%,这样无疑是一次划算的遍历,而且剩余%2的复制率,也很低。

老年代一般使用标记/清除或者标记/整理算法。
老年代存活率高,适合这两个算法。

永久代在一般情况下不做回收。

那么什么时候做Minor GC(新生代GC)和Full GC(老年代GC):
Minor GC:Minor GC非常频繁,因为新生代基本都是朝生夕死,所以在Eden空间不足以为对象分配内存时触发一次GC。

Full GC:Full GC一定会伴随着一次以上的Minor GC,也好理解,因为Minor GC后会也许会有对象进入老年代。当老年代满的时候自然会GC。Full GC速度非常慢,是Minor GC 的十倍以上。当老年代内存满的时候或者显式地调用System.gc()时会Full GC。

最后贴一下参考的可作为GC Roots的对象
①虚拟机栈(栈桢中的本地变量表)中的引用的对象,就是平时所指的java对象,存放在堆中。
②方法区中的类静态属性引用的对象,一般指被static修饰引用的对象,加载类的时候就加载到内存中。
③方法区中的常量引用的对象,
④本地方法栈中JNI(native方法)引用的对象

指路一篇深度好文,讲解十分详细。链接放在底下。
https://www.jianshu.com/p/76959115d486

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值