读书笔记-->Java内存分配策略初识

引言  

作为Java或Android程序员,大多时候我们不需要关系对象在内存中是如何分配,也不用担心对象占用的内存何时被系统回收。如果在开发过程中完全依赖系统帮助我们进行内存管理,那么后果将不堪设想。内存溢出,内存泄露,频繁GC等这些常见内存问题都是未对内存进行合理分配导致的,因此掌握JAVA内存分配策略是至关重要的。最近在读神作《深入理解Java虚拟机》,因此写下本文记录自己的读书心得。

走出误区  

我记得大学读书的时候,老师是这样教我们的:JAVA语言中是使用引用计数算法来判断对象是否存活。每个对象都有一个引用计数器,当被引用一次,引用计数器的值增加1;当引用失效时,引用计数器的值减一。这种观念陪伴了我很久,直到某次面试的时候才知道这是错误的。然而JAVA语言并没有选择引用计数算法来判断对象是否存活,最主要的原因是它很难解决对象之间的相互循环引用的问题。

public class ReferenceCountingGC {
	
	public Object instance = null;
	
	private static final int _1MB = 1024 * 1024;
    //这个成员属性的意义就是占一点内存,以便能在GC日志中看清楚是否被回收过
	private byte[] bigSize = new byte[2 * _1MB];
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ReferenceCountingGC objA = new ReferenceCountingGC();
		ReferenceCountingGC objB = new ReferenceCountingGC();
		objA.instance = objB;
		objB.instance = objA;
		objA = null;
		objB = null;
		//如果这里发生GC,那么objA和objB是否能被回收?
		System.gc();
	}

}
如果虚拟机是采用引用计数算法的话,那么objA和objB对象是无法回收的,因为它们各自持有对方的引用。然而通过查看GC日志,可以发现objA和objB对象可以被虚拟机回收。这也说明虚拟机并不是采用引用计数算法来判断对象是否存活。

根搜索算法

JAVA是采用根搜索算法来判断对象是否存活的。该算法的基本思路就是通过一系列名为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则此对象是不可用的。


如上图所示,虽然OBJ4和OBJ5有关联,但是他们到GC Root不可达,所以他们将会被判断为可回收对象。 在Java语言中,可作为GC Roots的对象包括下面几种:  

1.虚拟机栈(栈帧中的本地变量表)中的引用的对象。  

2.方法区中的类静态属性引用的对象。  

3.方法区中的常量引用的对象。  

4.本地方法栈中JNI(即一般说的Native方法)的引用对象。  

如果对以上四种类型不太明白,在下篇文章中介绍Java内存具体是如何进行分配的。

引用的四种类型

在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种,这四种引用的强度逐渐减弱。

1.强引用是最经常打交道的引用,通过new出来的引用都是强引用,只要强引用存在,GC宁可抛出outOfMemory,也不会回收掉被引用的对象。

2.软引用用于描述一些还有用,但是非必须的对象。对于软引用关联着的对象,在系统将要发生溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果此次回收还未有足够的内存,才会抛出内存溢出异常。

3.弱引用也是用来描述非必须的对象,但是它的强度比软引用更弱一些,被关联的对象只能生存到下一次GC发生之前。当GC工作时,无论当时内存是否足够,都会回收掉只被弱引用关联的对象。

4.虚引用是最弱的一种引用关系。一个对象是否有虚引用存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。设置虚引用的唯一目的是希望在这个对象被GC回收时收到一个系统通过。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值