1
JVM中的存储空间分为堆(heap)和栈。堆呢,放程序运行过程中创建的对象,而栈呢主要放static方法与static 变量.
堆内存中又分为两个区。新对象区,和老对象区。新对区又分为三个小区:伊甸园区,From区,To区。伊甸园区用来存放新创建的对象。当伊甸园区放满后,JVM系统做达到性测试,主要检测那些由根集合出发而不可到达的,这此对象被JVM回收。并且将所有活动对象从伊甸园区拷贝到To区,此时一些对象从发生状态变化。有此对象从To区域被拷贝到From区域,此时From区域就有对象。整个过程都是由JVM来完成的。
老对象区域中的对象仍然有一个较长的生命周期。大多数JVM系统垃圾对象,都来源于“短命”对象,经过一段时间后被转入老对象区域,就成了垃圾对象。
2 JVM中对象的生命周期
对象整个生命周期分为七个阶段:创建阶段,应用阶段,不可视阶段,不可到达分阶段,可收集阶段,终结阶段,释放阶段。
对象的创建要经过以下5个步骤的:
1)为对象创建空间
2)开始构造对象
3)递归调用其超类的构造方法
4)进行对象实例初始化和变量初始化
5)执行构造方法体
对象创建原则:
1) 避免在循环体中创建对象。
2) 尽量及时使对象符合垃圾回收标准
3) 不要采用过深层次继承
如:
for(int i=1;i<1000;i++){
Object o=new Object();
}
执行的效率远比不上。
Object o=null;
for(int i=0;i<1000;i++){
o=new Object();
}
采用这种方式,仅在内存中保存一份该对象的引用。
而不像上面的方法产生大量的对象。浪费大量内存,添加了垃圾回收的负担。
在程序设计中要做到“勿以恶小而为之”
对象应用阶段:
一个应用阶段的对象应具备以下特征:
1) 系统至少维护着对象的一个强引用
2) 所有对该对象的用都是强引用,除了我们显式地使用了软引用,弱引用和虚引用外。
强引用:是指从JVM根集出发遍寻堆中所有到达对象的路径,
软引用:当内存不足时才回收这类内存,因为当内存足够时通常不回收,适合较长生命周期对象。
弱引用:弱引用对象最容易被GC回收。一旦弱引用置为NULL时,这个对象引用就不存在了,GC能够回速回收该对象的空间。如
import java.lang.ref.WeakReference;
A a=new a();
//把a至为弱引 用
WeakReference wr=new WeakReference(a);
a=null;
if(wr!=null){
a=wr.get();
}else{
a=new A();
wr=new WeakReference(a);
}
不可视阶段
说明我们在其它区域已经不可以再引用它。如本地变量的引用,例子略。
不可到过阶段
找不到的对象,
可收集阶段,终结阶段和释放分阶段
在这个阶段的对象具有以下特征:
1 回收器发现该对象不可到达。
2 finally 方法已被执行
3 对象空间已被重用
JAVA的析构方法finalize
类似于C++的析构函数。通常我们在程序的最后使用用super.finalize()来实现从下到上的finalize的调用。通常我们在finalize方法中释放一些非常重要的资源如:I/O操作,数据库连接。由于GC调用finalize的时间是不确定的,我们需要通过其它手段释放其占用的资源如:
public Class A{
Object a=null;
public A(){
System.out.println("创建对象A");
a=new Object();
}
proctected void destroy(){
a=null;
System.out.println("释放a对象");
}
proctected void finalize() throws java.lang.Throwable{
destroy();
super.finalize(); //递归调用超类的finalize()
}
}
JAVA程序设计中有关内存的管理经验:
1 不再使用的变量要尽早将不用的对象赋为NULL,这将加速GC的工作。
2 尽量少用finalize函数,因为它会加GC的工作量。
3 如果经常用到图片,可以使有soft引用类型。这样能防止memory outof
4 注意使用集合数据类型,因为数组,树,图。对GC来说回收更复杂,注意一些static 和全局变量,因为往往容易引起悬挂对象和内存浪费。
5 尽量避免在类的权造器中创建初始化大量对象。
6 避免强制系统做垃圾回收(显式调用方法System.gc())
7 尽量避免显式申请数组空间。
8 尽量用对象池。
posted on 2006-04-11 10:55
有猫相伴的日子 阅读(248)
评论(0) 编辑 收藏 所属分类:
j2ee