您的位置:首页 > 编程语言 > Java开发

Java内存管理的小技巧

2017-03-04 09:40 239 查看
尽可能多地掌握Java的内存回收机制,垃圾回收机制是为了更好地管理java虚拟机的内存。这样才能提高java程序的运行性能。

1、尽量使用直接量

当需要使用字符串,还有Byte 、Short、Integer、Long、Float、Double、Boolean、Character包装类的实例时,程序不应该采用new的方式来创建对象。而应该直接采用直接量来创建他们。

例如,程序需要“hello”字符串,应该采用如下代码:

String str=“hello”;

上面的这种方式会创建一个“hello”字符串,而且JVM的字符串缓存池还会缓存这个字符串,当时如果程序使用如下代码:

String str=new String("hell");

此时程序同样创建了一个缓存在字符串缓存池中的“hell”字符串,除此之外str所引用的String对象底层还包含一个char【】数组,这个char【】数组里依次存放了h、e、l、l、o等字符串。

2、使用StringBuilder和StringBuffer进行字符串链接

String 、StringBuilder、StringBuffer都可以代表字符串,其中String代表字符序列不可变的字符串,而StringBuilder和StringBuffer都代表字符序列可变的字符串。

如果程序使用多个String对象进行字符串链接运算,在运行时将生产大量临时字符串,这些字符串会保存在内存中从而导致程序性能下将。

3、尽早释放无用对象的引用

大部分时候,方法局部引用变量所引用的对象会随着方法结束而变成垃圾,因为局部变量的生存周期很短,当方法运行结束时,改方法内的局部变量就结束了生命期限。因此大部分时候程序无须将局部、引用变量显式设为null;

例如下面的info()方法。

public void info(){
Object obj=new Object();
System.out.println(obj.toString());
System.out.pringtln(obj.hashCode);
obj==null;
}
上面程序中方法里定义了一个obj变量,随着info()方法里定义一个obj变量,随着info方法执行完成,程序中obj引用变量的作用域就结束了,原来obj所引用的对象就会变成垃圾。因此上面程序中obj==null;代码是没有必要的。

但是换一种情况来看,如果上面程序中info(方法改为如下形式。

public void info(){
Object obj=new Object();
System.out.println(obj.toString());
System.out.pringtln(obj.hashCode);
obj==null;

//执行耗时、耗内存操作
//或者调用耗时、耗内存的方法
.....
}
对于上面程序所示的info方法,若果在粗体字代码后还需要执行耗时、耗内存的操作。或者还需要调用耗时、耗内存的方法,那程序中粗体字代码就是有必要的;可以尽早释放对Object对象的引用。可能的情况是:当程序在执行粗体字代码之后的耗时、耗内存、操作时,obj之前所引用的Object对象可能被垃圾回收。

4、尽量少用静态变量

从理论上来说,java对象何时被回收由垃圾回收机制决定,对程序员来说是不确定的。但由于垃圾回收机制判断一个对象是否是垃圾的唯一标准就是该对象是否有引用变量引用它。因此推荐尽早释放对象的引用。

最坏的情况是某个对象呗static变量引用,那么垃圾回收机制通常是不会回收这个对象所占的内存。实例如下:

class Person{

    static Object obj=new Object();

}

对于上面的Object对象而言,只要obj变量还引用到它,它就不会被垃圾回收机制所回收。

obj变量是Person类的静态变量。因此它的生命周期与Person类同步。在Person类不被卸载的情况下,Person类对应的Class对象会常驻内存,直到程序运行结束。因此obj所引用的Object对象一旦被创建,也会常驻内存,直到程序运行结束。

5、避免在经常调用的方法、循环中创建java对象。

经常调用的方法和循环有一个共同的特征,这些代码段会被多次重复调用。示例如下:

public class Test{

    public static void main(String[] args){

        for(int i=0;i<10;i++){

            Object obj=new Object();

            //执行其他操作....

        }

    }

}

上面代码在循环中创建了1-个Object对象,虽然上面程序中的obj变量都是代码块的局部变量,当循环执行结束时这些局部变量都会失效。但由于这段循环导致Object对象会被创建10次,因此系统需要不断地为这10个对象分配内存空间。执行初始化操作。这10个对象的生存时间并不长,接下来系统又需要回收它们所占用的内存空间,在这种不断地分配、回收操作中,程序的性能受到巨大的影响。

6、缓存经常使用的对象。

如果有些对象需要被经常使用,可以考虑把这些对象用缓存池保存起来,这样当下次需要时就可以直接拿出这些对象来用。典型的缓存就是数据连接池,数据连接池里缓存了大量数据库连接,每次程序需要访问数据库时都可直接取出数据库连接。、

除此之外,如果系统还有一些常用的基础信息,比如信息化信息里包含的员工信息、物料信息等,也要考虑对它们进行缓存。实现缓存时通常有两种方式。

a、使用HashMap进行缓存。

b、直接使用某些开源的缓存项目。、

直接使用HashMap进行缓存,程序员需要手动控制HashMap容器里key-value对不至于太大,因此当key-value太多时将导致HashMap占用过大的内存,从而导致性能下将。

缓存设计本身就是一种以牺牲系统空间来换取运行时间的技术,不管是哪种缓存实现。都会使用容器来保存已用过的对象,方便下次再用。而这个保存对象的容器将占用一块不算太大的内存,如何控制改容器的内存不至于过大,而容器又能保留大部分已用过的对象,这就是缓存设计的关键。

7、尽量不要使用finalize的方法。

8、考虑使用、softReference
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm java 内存 缓存 性能