大家都知道Java程序的运行离不开java虚拟机
,而Java虚拟机(HotSport VM)运行时的数据区大致可分为五个部分,分别为JAVA栈、本地方法栈、堆、方法区、程序计数器,其中JAVA栈、本地方法栈、程序计数器是线程私有的,方法区和堆是线程共享区。
堆中一般保存着所有引用类型的真实信息(即对象)、字符产常量池、静态变量,以方便执行器执行。
而堆的空间是有限的,JVM虚拟机又有何保证存储空间的充足的呢?这就需要用的垃圾回收机制
。
本文主要讲解GC清理垃圾常用的四种算法。
=========================================================================
当对象被创建时,就会在Java虚拟机的堆区拥有一块内存,在Java虚拟机的生命周期中,Java程序会陆续地创建无数个对象,加入所有的对象永久的占用内存,那么内存有可能很快被消耗光,最后引发内存空间不足的错误。因此必须采取一种措施来及时回收那些无用对象的内存,以保证内存可以被重复利用。
JAVA GC 机制,是Java与C++/C的主要区别之一,作为java开发者,一般不需要战门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题。
那GC常用的算法有哪些呢?
=====================================================================
-
标记-清除算法
-
标记-压缩算法
-
复制算法
-
分代收集算法
Step 1:标记(Marking):
GC通过遍历内存区辨别哪些内存在使用,哪些内容没有使用。并做好标记。
引用的对象以蓝色显卡。未引用的对象以金色显示。在标记阶段扫描所有对象以进行此确定。如果必须扫描系统中的所有对象,这可能是一个非常耗时的过程。
Step 2:清除(Normal Deletion):
清除阶段移除掉对象垃圾,并且用一个链表维护空闲的区域
内存分配器持有空闲内存区的引用,以便分配内存给新的对象
优点:
每个活着的对象的引用只需要找到即可,找到一个就可以判断它为活得。不用移动对象的位置。
缺点:
-
效率比较低(递归与全堆对象遍历),每个活着的对象都要在标记阶段遍历一遍。
-
所有对象都要在清除阶段扫描一遍,算法复杂度高。
-
没有移动对象,导致可能出现需要碎小的空间无法利用(可能导致空间利用率低)。
基于标记-清除法的缺点—无法利用碎小的空间,提出了我们的标记-压缩算法。不同之处在于在第二个阶段,该算法并没有直接堆死亡的对象进行清理,而是将所有存活的对象进行整理,放在同意区域的另一处空间,然后把剩下的所有对象全部清除,这样就达到了标记-整理的目的。
通过一起移动引用的对象,这使得新的内存分配更容易和更快
优点:
不会产生大量的碎片空间
缺点:
如果存活的对象过多,整理阶段就会执行较多复制操作,导致算法效率低。
复制算法与标记-压缩算法的不同之处在于不是在同一个区域进行复制,而是将所有存活的对象复制到另一个区域。
该算法将内存平均的分为两个部分,然后每次使用其中的一部分,当这部分内存存满的时候,将内存中所有存活的对象复制到另一个内存中,然后将之前的内存清空,只是用这部分内存,然后循环。
优点:
实现简单,不产生内存碎片
缺点:
每次运行,总有一半内存是空的,导致内存的利用率只有50%。
标记和压缩算法存在的问题
标记和压缩算法对java虚拟机而言会比较耗时。当java虚拟机分配了越来越多的对象之后,GC就会花费更多的时间。然而,绝大多数的对象存活时间都比较短。这样我们可以把存活时间长的对象和短的对象隔离开。GC就会拥有更高的效率。
Y轴显示分配的字节数,X访问显示随时间分配的字节数。
随着时间的推移,分配的对象越来越少。事实上,大多数物体的寿命都很短。
现在的虚拟机GC大多数采用分代收集算法,它根据对象的生存周期,将堆分为新生代和老年代。
分代收集算法思想:
-
在新生代中,由于对象生存期短,每次回收都会有大量的对象死去,那么这时就采用复制算法。
-
老年代里的对象存活率高,没有额外的空间进行分配,所以可以使用标记-清除或者标记-压缩进行清除。
分代收集过程
- 新生代(Young)分为Eden区。From和To区
2.几乎所有新的对象都会在Eden空间分配内存,两个survivor空间一开始都是空的。
3.对着对象的不断创建,Eden区被填满
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)
最后
做任何事情都要用心,要非常关注细节。看起来不起眼的、繁琐的工作做透了会有意想不到的价值。
当然要想成为一个技术大牛也需要一定的思想格局,思想决定未来你要往哪个方向去走, 建议多看一些人生规划方面的书籍,多学习名人的思想格局,未来你的路会走的更远。
更多的技术点思维导图我已经做了一个整理,涵盖了当下互联网最流行99%的技术点,在这里我将这份导图分享出来,以及为金九银十准备的一整套面试体系,上到集合,下到分布式微服务
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mg-vNak3L5O-1713847070986)]
[外链图片转存中…(img-5K83S8Xc-1713847070986)]
[外链图片转存中…(img-vhDiLPns-1713847070987)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!