博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jvm基础知识四---垃圾回收面临的问题
阅读量:4304 次
发布时间:2019-05-27

本文共 1215 字,大约阅读时间需要 4 分钟。

如何区分垃圾

 

 

上面说到的“引用计数”法,通过统计控制生成对象和删除对象时的引用数来判断。垃圾回收程序收集计数

为0的对象即可。但是这种方法无法解决循环引用。所以,后来实现的垃圾判断算法中,都是从程序运行的根节
点出发,遍历整个对象引用,查找存活的对象。那么在这种方式的实现中,垃圾回收从哪儿开始的呢?即,从
哪儿开始查找哪些对象是正在被当前系统使用的。上面分析的堆和栈的区别,其中栈是真正进行程序执行地
方,所以要获取哪些对象正在被使用,则需要从Java栈开始。同时,一个栈是与一个线程对应的,因此,如果

 

有多个线程的话,则必须对这些线程对应的所有的栈进行检查。

   yy

 

同时,除了栈外,还有系统运行时的寄存器等,也是存储程序运行数据的。这样,以栈或寄存器中的引用为

起点,我们可以找到堆中的对象,又从这些对象找到对堆中其他对象的引用,这种引用逐步扩展,最终以null引
用或者基本类型结束
,这样就形成了一颗以Java栈中引用所对应的对象为根节点的一颗对象树,如果栈中有多
个引用,则最终会形成多颗对象树。在这些对象树上的对象,都是当前系统运行所需要的对象,不能被垃圾回
收。而其他剩余对象,则可以视为无法被引用到的对象,可以被当做垃圾进行回收。
因此,垃圾回收的起点是一些根对象(java栈, 静态变量, 寄存器...)。而最简单的Java栈就是Java程序执行的
main函数。这种回收方式,也是上面提到的“标记-清除”的回收方式

 

如何处理碎片

由于不同Java对象存活时间是不一定的,因此,在程序运行一段时间以后,如果不进行内存整理,就会出现零
散的内存碎片。碎片最直接的问题就是会导致无法分配大块的内存空间,以及程序运行效率降低。所以,在上
面提到的基本垃圾回收算法中,“复制”方式和“标记-整理”方式,都可以解决碎片的问题。

如何解决同时存在的对象创建和对象回收问题

垃圾回收线程是回收内存的,而程序运行线程则是消耗(或分配)内存的,一个回收内存,一个分配内存,
从这点看,两者是矛盾的。
因此,在现有的垃圾回收方式中,要进行垃圾回收前,一般都需要暂停整个应用
(即:暂停内存的分配),然后进行垃圾回收,回收完成后再继续应用。
这种实现方式是最直接,而且最有效
的解决二者矛盾的方式。
但是这种方式有一个很明显的弊端,就是当堆空间持续增大时,垃圾回收的时间也将会相应的持续增大,对应
应用暂停的时间也会相应的增大。一些对相应时间要求很高的应用,比如最大暂停时间要求是几百毫秒,那么
当堆空间大于几个G时,就很有可能超过这个限制,在这种情况下,垃圾回收将会成为系统运行的一个瓶颈。为
解决这种矛盾,有了并发垃圾回收算法,使用这种算法,垃圾回收线程与程序运行线程同时运行。在这种方式
下,解决了暂停的问题,但是因为需要在新生成对象的同时又要回收对象,算法复杂性会大大增加,系统的处
理能力也会相应降低,同时,“碎片”问题将会比较难解决。

 

你可能感兴趣的文章
.net core webApi 上传附件
查看>>
Hadoop 配置
查看>>
解决overflow: auto在Ios中滑动不流畅
查看>>
Linux内核分析 期中总结
查看>>
RHEL8.0-beta-1.ISO
查看>>
Sublime Text 2以及Zen Coding
查看>>
scrapy相关
查看>>
[Android] 状态栏的一些认识
查看>>
[iOS]圆形进度条及计时功能
查看>>
【教程】模拟登陆百度之Java代码版
查看>>
最短路问题
查看>>
杭电ACM 2052 Picture
查看>>
LeetCode 350. Intersection of Two Arrays II
查看>>
DB2时间操作
查看>>
滚动相册
查看>>
《剑指offer》连续子数组的最大和
查看>>
CAD 快捷键Ctrl+2 Ctrl+3
查看>>
SU Demos-06Selecting Traces
查看>>
谈谈__proto__和prototype的区别
查看>>
中正平和的出处
查看>>