JVM垃圾回收与内存分配(一)

概述

垃圾回收,GC,出现的时间比java要长很久。一直以来GC所研究的问题就是三个:
1、哪些东西需要回收?
2、什么时候回收?
3、如何回收?
通过JVM的内存管理我们可知,程序计数器、虚拟机栈、本地方法栈都是线程私有的空间,生命周期与线程相同,其所需要的空间大小也是在编辑器可以确定(虽然可以动态修改,但影响不大)。顾JVM的内存回收主要是针对虚拟机堆和方法区进行回收。
一个对象如果没有任何的引用指向它,或者说它没用了,那么它就可以死去了,否则应该活着,垃圾回收应该把死去的对象回收掉。
jvm是如何判断对象是活着还是死去的呢?以下几种算法

引用计数法

引用计数器法:给对象中加入一个引用计数器,当某个地方引用该对象时,计数器加1,当某一个引用失效时,计数器减1,任何时刻计数器都为0的对象为死去对象。
特点:该算法实现简单,效率较高。
很多地方使用比如微软的COM、ActionScript3的FlashPlayer等等。但是Java并没有选择它,主要以为它很难解决对象之间相互引用的问题。比如说:两个对象A和B,没有外界引用他们,但是他们之间互相引用,此时他俩的计数器都为1,但是这两个对象确实没有用了,这种情况引用计数器法即满足不了要求了。

根搜索算法

java和Csharp都是采用的此算法。此算法的基本思路是:在程序中,通过一系列被称作“GC roots”的对象作为起点,通过这些起点向下搜索,搜索所经过的路径叫做“引用链”。当起点到某个对象之间没有任何引用链时(即起点到此对象不可达),这个对象即为无用对象。
在java中可以作为GC roots的对象有:
1、虚拟机栈中的本地变量表中引用的对象
2、方法区中的静态引用对象
3、方法区中的常量引用对象
4、本地方法中JNI的引用对象
Java将引用分为四种类型,如下:

强引用

它是程序中普遍存在的引用,比如Object obj = new Object();这就是一个强引用。只要强引用存在,那么垃圾回收器永远不会回收该对象。

软引用

软引用表示程序中可有可无的对象,对于此类对象,当虚拟机将要发出内存溢出之前,先将此类对象列入回收范围准备进行二次回收,若此次回收仍然没有足够内存,才会抛出内存溢出异常。

弱引用

若引用也表示可有可无的对象,但他比软引用更低级,被标记为弱引用的对象只有短暂的生命周期,当下一次垃圾回收线程开始时,无论内存是否足够,发现弱引用对象一定会回收他们。

虚引用

虚引用的级别最低,无论是否标记为虚引用,对它本身的生命周期没有任何的影响。引入虚引用的唯一目的就是在该对象被回收时,收到一个系统通知。

对象的finalize()方法

一个对象即使与GC roots对象之间没有任何引用链,那么它也不会马上死掉,一个对象被回收至少要经过“两次标记”过程。
第一次标记:
当一个对象到GC roots不可达时,垃圾回收器首先对改对象进行第一次标记,并查看该对象是否重写了finalize方法、finalize方法是否被执行过。当该对象的finalize方法被重写并且没有执行过时,虚拟机会执行该对象的finalize方法,并且稍后(具体时间不确定,因为垃圾回收线程的优先级别很低)将对其进行第二次标记。
第二次标记:
进行第二次标记时,若发现该对象任然与GC roots对象不可达,此时将该对象放入“即将回收集合”,它才会被回收,由此可见在finalize方法中该对象可以挽救自己,可将自己赋值给一个变量或者任何一个引用链,那么进行第二次标记时,垃圾回收器将会忽略该对象,并将该对象认为是活着的。
需要注意,虚拟机只会对某个对象的finalize方法执行一次,如果被执行过,那么下次标记时将不会在执行该对象的finalize方法。
finalize方法运行代价高昂,无法保证对象之间被执行的顺序,不建议使用。

方法区的回收

方法区,即sun公司JVM的永久代,虚拟机规范中规定,虚拟机可以不对永久代进行回收,因为此处的回收效率并不高,远远不及堆中回收的效率。但对于大量使用反射的虚拟机来说应该具备类的卸载功能。在永久代的回收主要有无用常量的回收和无用类的回收。
无用常量的回收:
比如说方法区常量池中的字面值“abc”,若系统中没有任何地方有该值的引用,那么它可以被回收。
无用类的回收:
类的回收需要满足一下三个条件:
1、该类的所有实例被回收
2、加载该类的ClassLoader被回收
3、该类的Class对象没有任何地方被引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值