jvm垃圾回收思考(1)

        JVM本身具有垃圾回收机制,所以很多开发人员认为不需要理解jvm的内存管理部分。其实,深入理解jvm的内存管理机制可以帮助我们更好地编写高质量的代码,并减少内存泄露问题,同时对jvm的运行进行性能调优。

        为了引入话题,首先我们看以下一段代码

public class OutOfMemTest {
	public static void main(String[] args){
		List<Object> v = new ArrayList<Object>(10);
		while(true) {
			Object o = new Object();
			v.add(o);
		}
	}
}
        运行后很快程序会出错,抛出错误java.lang.OutOfMemoryError: Java heap space,表示堆空间溢出,程序退出。我们再看以下一段代码

public class JVMTest {

	public static void main(String[] args) throws InterruptedException {
		JVMTest test = new JVMTest();
		while(true){
			test.testList();
		}
	}
	
	private void testList(){
		List<Object> v = new ArrayList<Object>(10);
		Object o = null;
		int i = 0 ;
		while(i++<100) {
			o = new Object();
			v.add(o);
		}
	}
	
}

        上述代码,运行会发现没有出现内存溢出的问题,同样都是有一个无限死循环,而第一段代码会内存溢出,但第二段代码却可以正常运行。而这里就具体涉及到JVM的垃圾回收的相关问题。

        垃圾回收需要考虑的是三个问题:

        1、回收哪些数据;

        2、何时回收;

        3、如何回收。

        针对第一个问题,回收哪些数据,主要是两种算法:

       (1)引用计数法,简单来说每次生成一个对象,都会有一个引用指向它,而当该将该引用置为null,则引用会减一,当该对象没有被引用时,则表示可以被回收。

       (2)根搜索算法,指的是从一个跟引用开始进行遍历,遍历到叶子节点为止,并将上述节点进行标记,而那些没有被标记的节点,则为不可达状态,表示可以被回收。


             如上图中红色标记部分则为不可达的对象,会在垃圾回收的过程中进行回收。而根搜索算法中的可以被做为根节点的对象主要为一下三个:

  • JVM栈中引用的对象;
  • 方法区中的静态变量以及常量引用的对象;
  • 本地栈中JNI中引用的对象;

             这里需要注意的是跟搜索算法中要注意引用类型,强引用,软引用,弱引用以及虚引用。

          针对第二个问题,具体这些对象何时回收,一般是当对象所占用的堆空间过大,会进行回收,针对不同的回收算法,这个具体的触发回收的点也是稍有不同。

          第三个问题,如何进行回收,就会涉及到具体的相关回收算法。主要由四种:标记-清除算法,复制算法,标记-整理算法,分代算法;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值