Java中的GC(垃圾回收)

来源:互联网 发布:矩阵乘法规则 编辑:程序博客网 时间:2024/06/06 00:36

     在Java 中,垃圾回收是个非常重要的概念,主要作用是回收程序中不再使用的内存。在c/c++语言开发中,开发人员必须非常仔细的管理好内存的分配与释放,否则可能会导致程序的崩溃。为了减轻开发人员的负担,Java语言提供了垃圾回收器来自动检测对象的作用域,可自动的把不在被使用的内存空间释放掉。垃圾回收器只有负责三部分:分配内存、确保被引用对象的内存不被错误的回收以及回收不再被引用的对象的内存空间。

     垃圾回收器一方面减轻开发人员的负担,保证程序的稳定性,一方面也带来问题,垃圾回收器必须跟踪内存的使用情况,释放没用的内存,在完成释放之后还需要处理堆中的碎片,这样会增加JVM的负担从而降低程序的执行效率。

   对于垃圾回收器来说,它使用有向图来记录和管理堆内存中的所有对象,通过有向图来识别哪些对象是“可达的”,哪些对象是“不可达的”。所有不可达的对象都是可以被垃圾回收器回收的。

     垃圾回收常用算法:

1,引用计数算法。简单但是效率低的算法。原理:在堆中对每个对象都有一个引用计数器;当对象被引用的时候,引用计数器就加1;当引用被置空或者离开作用域的时候,引用计数就减去1,由于这个方法无法解决相互引用的问题,因此JVM没有采用这个算法。

2,追踪回收算法。追踪回收算法利用JVM维护的对象引用图,从根结点开始遍历对象的引用图,同时标记遍历到的对象。当遍历结束后,未被标记的对象就是目前已经不被使用的对象,可以被回收了。

3,压缩回收算法。压缩回收算法思路:把堆中活动的对象移动都堆中的一端,这样就会在堆中另外一端留出来一块空闲区域,相当于把堆中的碎片进行处理。虽然此方法可以大大简化消除堆碎片的工作,但是每次处理都会来性能的损失。

4,复制回收算法。参考博客链接http://blog.csdn.net/sinat_36246371/article/details/53002209

首先将内存分为大小相等的两部分(假设A、B两部分),每次呢只使用其中的一部分(这里我们假设为A区),等这部分用完了,这时候就将这里面还能活下来的对象复制到另一部分内存(这里设为B区)中,然后把A区中的剩下部分全部清理掉。

这样一来每次清理都要对一半的内存进行回收操作,这样内存碎片的问题就解决了,可以说简单,高效。


这里写图片描述

但是呢,肯定发现了,本来挺大一片地方,现在只能用一半,搞得挺不爽的,世界上本来没有免费的饭菜,就算是用空间换取时间吧。

5,复制回收算法的缺点:每次算法执行时,所有处于活跃状态的对象都要被复制,这样效率很低。按代回收算法。此算法主要思想:把堆分成两个或者多个子堆,每一个子堆被视为一代。算法在运行的过程中优先收集那些“年幼”的对象,如果一个对象经历多次收集仍然“存活”,那么就可以把这个对象转移到高一级的堆里,减少对其的扫描次数。