欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

胡八一之Java(五):java内存回收,

来源: javaer 分享于  点击 49989 次 点评:107

胡八一之Java(五):java内存回收,


 

当一个对象在堆内存中运行时,有以下三种状态:

可达状态:当一个对象有一个以上的引用变量引用它,程序可以通过引用变量来调用对象的属性和方法。在有向图中,这就属于可达。

可恢复状态:如果一个对象没有任何变量再引用它,那么它将先进入可恢复状态。系统的垃圾回收机制准备回收该对象所占的内存,在回收该对象之前,系统会调用可恢复状态的对象finalize方法进行资源清理,如果系统调用该方法让对象有一个以上的变量重新引用它,则这个对象就会再变成可达状态,否则变成不可达状态。

不可达状态:当对象没有引用变量引用它时,而且调用finalize方法也没有使其变为可达状态,则系统将会回收其对象所占的内存空间。

一个对象可以被一个方法的实例变量引用,可以被其它类的类变量引用,也可以被其他对象的实例对象引用。当某个对象被其他类的类变量所引用时,只有当这个类销毁时,该对象才会进入可销毁状态;当某个对象被其他对象引用时,只有这个对象销毁时或进入不可达状态时,这个对象才会进入不可达状态。

 

java对象对象的引用有四种:强引用、软引用、弱引用,虚引用

其中我们编程经常可以采纳的有两种:强引用、软引用。

强引用:程序创建一个对象,并把这个对象赋给一个引用变量。这种引用状态是Java编程中最常见的,被强引用的对象绝不会被垃圾回收机制回收,即使内存非常紧张,jvm也不会回收这种强引用所引用的对象,所以这也是Java内存泄漏的主要原因之一。

(内存泄漏:程序运行过程中会不断地分配内存空间,那些不在使用的内存空间将会被回收,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,那就是内存泄漏)

软引用:通过SoftReference类来实现,当系统的空间足够时,对象不会被回收,当内存紧张时,内存才会回收对象。

package aaaaa;

import java.lang.ref.SoftReference;

class Person {
	String name;
	int age;
	public Person(String name,int age){
		this.age=age;
		this.name=name;
	}
	public String toString(){
		return "Person[name]:="+name+",   age="+age;
	}
}
public class Test{
	
	public static void main(String args[]) throws Exception{
     SoftReference<Person>[] people =new SoftReference[100000];	
     for(int i =0;i<people.length;i++){
    	 people[i] =new SoftReference<Person>(new Person("名字"+i,(i+1)*4%100));
     }
     System.out.println(people[2].get());
     System.out.println(people[4].get());
     //通知系统进行垃圾回收
     System.gc();
     System.runFinalization();
     //垃圾回收机制运行会,
     System.out.println(people[2].get());
     System.out.println(people[4].get());
	}
}

运行结果:

Person[name]:=名字2,   age=12
Person[name]:=名字4,   age=20
Person[name]:=名字2,   age=12
Person[name]:=名字4,   age=20

此时内存没有达到紧张状态,所以没有清除2和4对象,可通过在cmd中为JVM指定较小的堆内存来达到效果,如下

java -Xmx2m  -Xms2m 类名

Java内存管理小技巧:

1、尽量使用直接量

当使用字符串,Byte,Short,Integer,Float,Double,Boolean,Character包装类的实例时不应该使用new来创建对象,而应该直接

使用

如:

String a = new String("hello");

这种方式会创建一个“hello"字符串,而且JVM的字符缓冲池会缓存这个字符串,除此之外,a所引用的String对象底层还包含一个char数组,char数组里依次存放了hello 的每个字符。

String a ="hello";

而这种就不会产生char数组。

2、使用StrinBuilder和StringBuffer来进行字符串连接

String 代表字符序列不可变字符串,而StringBuffer和StringBuilder代表字符序列可变字符串。

如果使用String字符串来连接字符串,则会产生大量零时字符串。

3、尽早释放无用对象,将对象显式的设置为null

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

//下面是一些耗内存的操作,完全需要释放上面对象的内存空间

....
}

4、尽量少用静态变量

静态变量生命周期与类同步,当遇到常驻内存的class ,一旦被创建,就会常驻内存。

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

6、缓存经常使用的对象

7、尽量不要使用finalize方法

8、考虑使用SoftReference

相关文章

    暂无相关文章
相关栏目:

用户点评