垃圾回收算法

一.为什么要有垃圾回收?

内存是有限的,如果一直申请资源,而不去释放资源,可用空间越来越少,就会引起内存泄漏问题。

二.垃圾回收主要回收哪个内存区域?

程序计数器:空间固定,每个线程都有一个程序计数器,跟随线程一起销毁。

栈:主要是局部变量,约定的变量出了作用域,就会被回收。

方法区:类对象,主要设计类加载,会但很少涉及类卸载。

堆:new对象(主要回收空间)

三.如何确定对象是不是垃圾?

1.引用计数

使用额外计数器,记录某个对象有多少个引用指向它。

每次产生一次引用,就把计数器++;销毁一次引用,就把计数器--;如果对象的引用计数为0,则说明没有引用指向该对象,此时改对象就是垃圾可以被回收。

缺陷:(1)多线程中,需要也是引用一个对象时,就会引起线程安全问题。

(2) 如果是小的对象,引用次数过多,引用计数就会造成较大的空间开销。

(3)循环引用问题,即a和b相互引用,如果引用被销毁,此时a和b的引用计数都还是1,都不能被销毁,也不能被引用。

2.可达性分析

以代码中的特殊变量GCRoot为起点,然后以起点出发,能够访问到的变量,就设置为"可达"。

GCRoot:(1)栈里面的局部变量,所有线程的所有栈的所有栈帧的所有局部变量表中的所有变量;(2)常量池中对应的对象;(3)方法区中静态引用类型的成员。

四.具体如何回收垃圾?

1.标记清除

先通过可达性分析确定垃圾,就把垃圾直接释放掉,但是垃圾不是一个连续的内存空间,而new操作时,又要new出来一段连续的内存空间,就引起了内存碎片问题,造成了空间的浪费。

2.复制算法

将内存一分为二,在进行垃圾释放之前,先将要保留的对象复制到另一侧内存空间,然后再将之前的一侧的空间全部释放,就解决了内存碎片问题。但是将内存一分为二就引入了新的问题——空间利用率低。

3.标记整理

类似于链表删除元素,针对内存进行搬运操作,即解决了内存碎片问题,也解决了空间利用率低的问题,但是搬运操作耗时。

4.分代回收

将内存分为新生代和老年代。

将新创建的对象放到伊甸区,如果该对象活过了一轮GC就放入幸存区,进入幸存区的对象再经历了一轮GC后,又通过复制算法进入另一个幸存区中,如果经过多轮GC,该对象仍然存在,就说明该对象一时间不容易被销毁,就把它放入老年代中,进入老年代之后就通过标记整理算法进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值