四大垃圾回收算法七大垃圾回收器

JVM的运行时内存也叫做JVM堆,从GC的角度可以将JVM分为新生代、老年代和永久代

其中新生代默认占1/3堆内存空间,老年代默认占2/3堆内存空间,永久代占非常少的对内存空间

新生代又分为Eden区、SurvivorFrom区和SurvivorTo区, Eden区默认占8/10新生代空间,SurvivorFrom区和SurvivorTo区默认分别占1/10新生代空间;Eden区最小占3/5新生代空间,SurvivorFrom区和SurvivorTo区分别占1/5新生代空间,如下图所示:

永久代

永久代指内存的永久保存区域,主要存放Class和Meta(元数据)的信息。Class在类加载时被放入永久。永久代和老年代、新生代不同,GC不会在程序运行期间对永久代的内存进行清理,这也导致了永久代的内存会随着加载的Class文件的增加而增加,在加载Class文件过多时会抛出Out Of Memory异常,比如Tomcat引用Jar文件过多会导致JVM内存不足而无法启动。

需要注意的是,在Java 8 中永久代已经被元数据区(也叫做元空间)取代。元数据区的作用和永久代类似,二者最大的区别在于:元数据区并没有使用虚拟机内存,而是直接使用操作系统的本地内存。因此,元空间的大小不受JVM内存的限制,之和操作系统的内存有关。

在Java 8 中,JVM将类的元数据放入本地内存(Native Memory)中,将常量池和类的静态变量放入Java堆中,这样JVM能够加载多少元数据信息就不再由JVM的最大可用内存(MaxPermSize)空间决定,而由操作系统的实际可用的内存空间决定。

原文链接:https://blog.csdn.net/qq_45886144/article/details/124083079

一、四大垃圾回收算法

1、引用计数器算法

原理其实很简单,给运行的对象添加一个引用计数器,每当有一个地方引用它时,计数器+1;当引用失效时,计数器就-1,任何时刻计数器为0的对象,就视作不可能再被使用。这一种方式,实现简单,逻辑也清晰,大部分的情况下,它都可以达到很好的效果,尽管这样,计数器算法还是存在但是的,但是它无法解决循环引用的场景,这也是主流Java虚拟机没有选用这一算法的原因。

2、复制算法(Copying)

为了解决标记清除算法的效率问题,有人提出了复制算法。它将可用内存一分为二,每次只用一块,当这一块内存不够用时,便触发 GC,将当前存活对象复制(Copy)到另一块上,以此往复。这种算法高效的原因在于分配内存时只需要将指针后移,不需要维护链表等。但它最大的问题是对内存的浪费,使用率只有 50%。

但这种算法在一种情况下会很高效:Java 对象的存活时间极短。据 IBM 研究,Java 对象高达 98% 是朝生夕死的,这也意味着每次 GC 可以回收大部分的内存,需要复制的数据量也很小,这样它的执行效率就会很高。

优点:没有标记和清除的过程,效率高;没有内存碎片,可以利用bump-the-pointer实现快速内存分配。

缺点:需要双倍空间。

3、标记清除算法(Mark Sweep)

该算法很简单,使用通过可达性分析方法标记出垃圾,然后直接回收掉垃圾区域。简单粗暴,即标记删除的对象,对其进行内存回收;它的一个显著问题是一段时间后,内存会出现大量碎片,导致虽然碎片总和很大,但无法满足一个大对象的内存申请,从而导致 OOM,而过多的内存碎片(需要类似链表的数据结构维护),也会导致标记和清除的操作成本高,效率低下。

缺点:两次扫描,耗时严重;会产生内存碎片。

可达性算法

此算法的核心思想:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,当一个对象到 GC Roots 没有任何的引用链相连时(从 GC Roots 到这个对象不可达)时,证明此对象不可用。

4、标记压缩算法(Mark Sweep)

只是在标记清除的基础上,追加了碎片的散落问题,在清除之后进行了碎片的整理,但副作用是增了了GC的时间。

二、七大垃圾回收器

http://www.manongjc.com/detail/62-sjaactrbfltsjah.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值