什么是GC?

时间:2024-01-04 09:55:57 阅读:6

什么是GC?

问:什么是GC?

答: 在Java言语中,渣滓吸收(Garbage Collection,GC)是一个十分紧张的看法,它的主要作用是吸收步骤中不再使用的内存

在使用C/C++言语举行步骤开发时,开发职员必需十分仔细肠办理好内存的分派与开释,假如忘记大概错误地开释内存屡屡会招致步骤运转不正常乃至是步骤崩溃。为了减小开发职员的事情,同时增长体系的宁静性与安定性,Java言语提供了渣滓吸收器来主动检测目标的作用域,可主动地把不再被使用的存储空间开释掉。

具体而言,渣滓吸收器要卖力完成3项职责:分派内存、确保被引用目标的内存不被错误地吸收以及吸收不再被引用的目标的内存空间。

渣滓吸收器的存在一方面把开发职员从开释内存的繁复事情中摆脱出来,提高了开发职员的消费听从;另一方面,对开发职员屏蔽了开释内存的办法,可以制止因开发职员错误地利用内存而招致使用步骤的崩溃,确保了步骤的安定性。

但是,渣滓吸收也带来了成绩,为了完成渣滓吸收,渣滓吸收器必需跟踪内存的使用情况,开释没用的目标,在完成内存的开释后还必要处理堆中的碎片,这些利用一定会增长JVM的包袱,从而低落步骤的实行听从。

对目标而言,假如没有任何变量去引用它,那么该目标将不成能被步骤拜候,因此可以以为它是渣滓信息,可以被吸收。只需有一个以上的变量引用该目标,该目标就不会被渣滓吸收。

关于渣滓吸收器来说,它使用有向图来纪录和办理堆内存中的一切目标,经过这个有向图就可以识别哪些目标是“可达的”(有引用变量引用它就是“可达的”),哪些目标是“不成达的”(没有引用变量引用它就是不成达的),一切“不成达”目标都是可被渣滓吸收的,示比如下:

上述代码在实行到i2=i1后,内存的引用干系如下图所示:

此时,假如渣滓吸收器正在举行渣滓吸收利用,在遍历上述有向图时,资源2所占的内存是不成达的,渣滓吸收器就会以为这块内存以前不会再被使用了,因此就会吸收该块内存空间。

渣滓吸收都是依据一定的算法举行的,底下先容此中几种常用的渣滓吸收算法。

  1. 引用计数算法(Reference Counting Collector)

引用计数作为一种简便但是听从较低的办法,其主要原理如下:在堆中对每个目标都有一个引用计数器;当目标被引用时,引用计数器加1;当引用被置为空或分开作用域的时,引用计数减1,由于这种办法无法处理互相引用的成绩,因此JVM没有接纳这个算法。

  1. 追踪吸收算法(TracingCollector)

追踪吸收算法使用JVM维护的目标引用图,从根结点开头遍历目标的使用图,同时标志遍历到的目标。当遍历完毕后,未被标志的目标就是现在已不被使用的目标,可以被吸收了。

  1. 紧缩吸收算法(CompactingCollector)

紧缩吸收算法的主要思绪如下:把堆中活动的目标挪动到堆中一端,如此就会在堆中别的一端留出很大的一块空闲地区,相当于对堆中的碎片举行了处理。固然这种办法可以大大简化消弭堆碎片的事情,但是每次处理都市带来功能的丧失。

  1. 复制吸收算法(CopingCollector)

复制吸收算法的主要思绪如下:把堆分红两个轻重相反的地区,在任何时候,仅有此中的一个地区被使用,直到这个地区的被斲丧完为止,此时渣滓吸收器会中缀步骤的实行,经过遍历的办法把一切活动的目标复制到别的一个地区中,在复制的历程中它们是紧挨着安插的,从而可以消弭内存碎片。当复制历程完毕后步骤会接着运转,直到这块地区被使用完,然后再接纳外表的办法持续举行渣滓吸收。

这个算法的优点是在举行渣滓吸收的同时对目标的安插也举行了安插,从而消弭了内存碎片。但是这也奉献了很高的代价:关于指定轻重的堆来说,必要两倍轻重的内存空间;同时由于在内存调停的历程中要中缀如今实行的步骤,从而低落了步骤的实行听从。

  1. 按代吸收算法(GenerationalCollector)

复制吸收算法主要的缺陷如下:每次算法实行时,一切处于活动形态的目标都要被复制,如此听从很低。由于步骤有“步骤创建的大局部目标的生命周期都很短,仅有一局部目标有较长的生命周期”的特点,因此可以依据这个特点对算法举行优化。按代吸收算法的主要思绪如下:把堆分红两个大概多个子堆,每一个子堆被视为一代。算法在运转的历程中优先搜集那些“年幼”的目标,假如一个目标颠末多次搜集仍旧“存活”,那么就可以把这个目标转移到高一级的堆里,变小对其的扫描次数。

稀有口试题:

  1. 现有如下代码:

当Float目标在第2行被创建后,什么时分可以被渣滓吸收?()

A.4行今后

B.5行今后

C.6行今后

D.7行今后

答案:C。在第6行后不再有目标引用Float目标了,因此可以被渣滓吸收。

2.下列关于渣滓吸收的说法中,准确的是()。

A.一旦一个目标成为渣滓,就立刻被吸收掉

B.目标空间被吸收掉之后,会实行该目标的finalize办法

C.finalize办法和C++的析构函数完善是一回事变

D.一个目标成为渣滓是由于不再有引用指着它,但是线程并非云云

答案:D。成为渣滓的目标,仅有本人次渣滓吸收器运转时才会被吸收,而不是立刻被算账,因此选项A错误。finalize办法是在目标空间被吸收前调用的,因此选项B错误。在C++言语中,调用了析构函数后,目标一定会被烧毁,而Java言语调用了finalize办法,渣滓却不一定会被吸收,因此finalize办法与C++的析构函数是不同的,以是选项C也不准确。关于D,当一个目标不再被引用后就成为渣滓可以被吸收,但是线程就算没有被引用也可以独立运转的,因此与目标不同。以是准确答案为D。

3、对否可以主动关照JVM举行渣滓吸收?

答案:由于渣滓吸收器的存在,Java言语本身没有给开发职员提供显式开释已分派内存的办法,也就是说,开发职员不克不及及时地调用渣滓吸收器对某个目标或一切目标举行渣滓吸收。但开发职员却可以经过调用System.gc()办法来“关照”渣滓吸收器运转,固然,JVM也并不会确保渣滓吸收器立刻就会运转。由于System.gc()办法的实行会中止一切呼应,去反省内存中对否有可吸收的目标,这会对步骤的正常运转以及功能形成极大的要挟,因此实践编程时,不保举经常使用这一办法。


版权声明:本文来自互联网整理发布,如有侵权,联系删除

原文链接:https://www.yigezhs.comhttps://www.yigezhs.com/qingganjiaoliu/41494.html


Copyright © 2021-2022 All Rights Reserved 备案编号:闽ICP备2023009674号 网站地图 联系:dhh0407@outlook.com