标签:java内存回收 java垃圾回收 jvm垃圾回收 垃圾回收算法 垃圾回收
在Java中,它的内存管理包括两个方面:内存分配和内存回收,这两个方面的工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险。但这也使很多程序员不关心内存分配的问题,导致很多程序低效耗费内存。
Java语言规范没有明确的说明JVM使用哪种垃圾回收算法。一般常用的算法有下列几种:
开始先看一个例子:
Person.java
package test;
import java.io.Serializable;
public class Person implements Serializable {
static final long serialVersionUID = 1L;
String name; // 姓名
Person friend; //朋友
public Person() {}
public Person(String name) {
super();
this.name = name;
}
}
Test.java
package test;
public class Test{
public static void main(String[] args) {
Person p1 = new Person("Kevin");
Person p2 = new Person("Rain");
Person p3 = new Person("Sunny");
p1.friend = p2;
p3 = p2;
p2 = null;
}
}
把上面Test.java中main方面里面的对象引用画成一个从main方法开始的对象引用图的话就是这样的(顶点是对象和引用,有向边是引用关系):
当程序运行起来之后,把它在内存中的状态看成是有向图之后,可以分为三种:
Person person = new Person("sunny");
此时不管系统资源有多么紧张都绝对不会被回收。软引用:通过SoftReference类实现,eg:SoftReference<Person> p = new SoftReference<Person>(new Person(“Rain”));
内存非常紧张的时候会被回收,其他时候不会被回收,因此在使用之前要判断是否已经被回收了。例如:
class AB {
protected void finalize() {
System.out.println("finalize.....");
}
}
public class JavaTest {
public static void main(String[] args) {
for (int i=0 ; i < 10000; i ++) {
new SoftReference<AB> (new AB());
}
}
}
结果为:finalize.....
finalize.....
finalize.....
结果不一定,看个人电脑了,也可能没有输出,需要创建更多的对象来逼着JVM回收软引用。
弱引用 :通过WeakReference类实现,eg : WeakReference<Person> p = new WeakReference<Person>(new Person(“Rain”));
不管内存是否足够,系统垃圾回收时必定会回收。
class AB {
protected void finalize() {
System.out.println("finalize.....");
}
}
public class JavaTest {
public static void main(String[] args) {
WeakReference<AB> wr = new WeakReference<AB> (new AB());
System.gc();
}
}
输出结果为:finalize.....
强制回收垃圾,若引用就会直接被回收
虚引用 :不能单独使用,主要是用于追踪对象被垃圾回收的状态。通过PhantomReference类和引用队列ReferenceQueue类联合使用实现,例子如下。
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Test{
public static void main(String[] args) {
//创建一个对象
Person person = new Person(“Sunny”);
//创建一个引用队列
ReferenceQueue rq = new ReferenceQueue();
//创建一个虚引用,让此虚引用引用到person对象
PhantomReference pr = new PhantomReference(person, rq);
//切断person引用变量和对象的引用
person = null;
//试图取出虚引用所引用的对象
//发现程序并不能通过虚引用访问被引用对象,所以此处输出为null
System.out.println(pr.get());
//强制垃圾回收
System.gc();
System.runFinalization();
//因为一旦虚引用中的对象被回收后,该虚引用就会进入引用队列中
//所以用队列中最先进入队列中引用与pr进行比较,输出true
System.out.println(rq.poll() == pr);
}
}
输出结果为 : null true
压缩和不压缩和复制
标签:java内存回收 java垃圾回收 jvm垃圾回收 垃圾回收算法 垃圾回收
原文地址:http://blog.csdn.net/jing_unique_da/article/details/45576029