JVM内存管理优化经验

来源:互联网 发布:mac os x vmware 卡 编辑:程序博客网 时间:2024/05/23 16:55

1、避免在循环体中创建对象

例如:.... ....
for ( int i = 0; i < 10000; i++) {
Object obj = new Object();
System.out.println(obj);
}
应修改为:
... ...
Object obj = null;
for(int i = 0; i < 10000;i++){
obj = new Object();
System.out.println(obj);
}
说明:采用第二种编码方式,仅在内存中保存了一份对该对象的引用,而不会像第一种编写方式产生大量的对象引用,从而使得对象尽早符合垃圾回收标准,被JVM回收。


2、不要对一个对象多次初始化

例如:... ...
public class A {
private Hashtable table = new HashTable();


public A() {
//将Hashtable对象table初始化两次
table = new Hashtable();
}
}
应修改为:
... ...
public class B {
private Hashtable table = new HashTable();


public B() {

}

说明:这种修改将使得程序在构造对象时所用时间减少一半。


3、软引用技术使得java应用可以更好地管理内存,稳定系统,防止系统内存溢出,避免系统崩溃。因此在处理一些占用内存较大,而且声明周期较长,但使用并不频繁的对象时应尽量使用该技术。上面代码说明,对于那些没有保留运行状态的对象,我们可以在对象被回收之后重新创建,但对于应用软引用的对象的初始化过程较为耗时,或对象的状态在程序运行过程中发生变化,都会给重新创建对象与初始化对象带来不同程度的麻烦,这时需要我们做好权衡。

使用实例:

     ... ...

            import java.lang.ref.SoftReference;
            ...
            A a = new A();
            ...
            //使用a
            ...
            //使用完a,将他设置为soft引用类型,并且释放强引用;
            SoftReference sr = new SoftReference(a);
            a = null;
            ...
            //下次使用时
            if (sr != null) {
                a = sr.get();
            }  else {
                    //GC由于内存不足,可能系统已回收了a的软引用,因此需要重新加载
                    a = new A();
                    sr = new SoftReference(a);
            }   
            ... ...
4、如果一个对象已经使用完,而且在其可视区域不再使用,此时应该主动将其设置为空(null)。这样做,可以帮助JVM及时发现这个垃圾对象,并且可以及时地回收该对象所占的系统资源。

 public void process() {
        try {
            Object obj = new Object();
            obj.doSomething();
       obj = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        while (isLoop) {
            //这个区域对于obj对象来说是不可视的了,因此下面代码编译出错
            obj.doSomething();
        }
    }

5、我们在设计类时,应尽量避免在默认构造函数中,构建、初始化大量的对象,或者进行复杂、耗时的运算逻辑。一个原因是在实例化自身时,造成较大的资源开销;另一个原因是,其子类在被实例化时,也同样会带来较大的系统资源开销。因为即使我们没有想调用父类的构造器创建大量无用的对象,但是系统会自动创建它们,而这些操作与过程对于我们来说是隐含的。


6、我们在采用强制系统垃圾回收(通过显示调用方法System.gc())的办法回收垃圾内存的方法,还是存在弊端的,应该尽量少用,或者说是在必要的时候应用


7、尽量避免显示申请数组空间。如果遇到数组中所保存的元素占用内存空间较大或数组本身长度较大时,我们可以采用软技术来引用数组,以“提醒”JVM及时回收垃圾内存。


8、做远程方法调用,使用瞬间值和实现java.lang.Serializable接口的问题。实现java.lang.Serializable是为了可以从远程环境以对象流的方式传输。将对象里的一些无关属性,设为瞬间值,则无关变量就不会被传输。


9、为了节省系统内存资源,不提前申请并不急需的内存空间。我们应当尽量在需要的时候创建对象。


10、如果需要使用经常用到的图片,可以使用soft应用类型。


11、尽量少用finalize函数。finalize函数是java给程序员提供的释放对象或资源的机会,但是会加大GC的工作量。



0 0
原创粉丝点击