1对象在内存中的状态,
class Node
{
Node next;
String name;
public Node(String name)
{
this.name = name;
}
}
public class NodeTest
{
public static void main(String[] args)
{
Node n1 = new Node("第一个节点");
Node n2 = new Node("第二个节点");
Node n3 = new Node("第三个节点");
n1.next = n2;
n3 = n2;
n2 = null;
}
}
JVM的垃圾回收机制采用有向图方式来管理内存中的对象
当一个对象在堆内存中运行时,根据它对应有向图的状态分为 http://blog.youkuaiyun.com/liuc0317/article/details/6149578
1可达状态:当一个对象被创建后,有一个以上的引用变量引用它。在有向图中可从起始顶点导航到该对象,那它就处于可达状态,程序可通过引用变量来调用该对象的属性和方法。
2可恢复状态:如果程序中某个对象不再有任何引用变量引用它,它将先进入可恢复状态,此时从有向图的起始顶点不能导航到该对象。在这个状态下系统的垃圾回收机制准备回收该对象所占用的内存,在回收该对象之前,系统会调用可恢复状态的对象的finalize方法进行资源清理,,如果系统在调用finalize方法重新让一个以上引用变量引用该对象,则这个对象再次变为可达状态,否则,该对象将进入不可达状态。
3不可达状态:当对象的所有关联度被切断,且系统调用所有对象的finalize方法依然没有使该对象变成可达状态,那这个对象将永久性地失去引用,最后变成不可达状态。
2java语言对对象的引用有如下4种
1强引用
2软引用 SoftReference
当系统内存空间充足时,软引用于强引用没有太大区别,当系统内存空间不足时,被软引用所引用的java对象可以被垃圾回收机制回收,
class Person
{
String name;
int age;
public Person(String name , int age)
{
this.name = name;
this.age = age;
}
public String toString()
{
return "Person[name=" + name
+ ", age=" + age + "]";
}
}
public class SoftReferenceTest
{
public static void main(String[] args)
throws Exception
{
SoftReference<Person>[] people =
new SoftReference[100];
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();
//垃圾回收机制运行之后,SoftReference数组里的元素保持不变
System.out.println(people[2].get());
System.out.println(people[4].get());
}
}
当修改SoftReference[100]数组长度为SoftReference[100000],系统内存空间不足,软引用所引用的对象会被回收
3弱引用WeakReference
相比软引用,弱引用的引用级别更低,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存,因此程序获取弱引用所引用的对象时必须小心空指针异常
4虚引用PhanttomReference 引用队列java.lang,ref,Reference
虚引用不能单独使用,主要作用就是跟踪对象被垃圾回收的状态,程序可通过检查与虚引用关联的引用队列中是否包含指定的虚引用,从而了解虚引用所引用的对象是否即将被回收
java的内存泄露
有一些java对象,他们处于可达状态。但程序以后永远都不会再访问它们,那它们所占用的内存空间也不会被回收,它们所占用的空间就会产生内存泄露。
垃圾回收机制
1跟踪并监控每个java对象,当某个对象处于不可达状态时,回收该对象所占用的内存。
2清理内存分配,回收过程中产生的内存碎片。
回收算法:
1串行回收 2并行回收3并发执行4应用程序停止5压缩(标记压缩)6不压缩(标记清除)7复制
分代的方式采用不同的回收设计
Young 年轻代
Old 老年代 不那么容易失去引用
Permanent 永久代 用于装载Class,方法等信息
对内存的分代回收
Young 年轻代:复制 次要回收
Old 老年代:标记压缩 主要回收
Permanent 永久代 通常不会回收
常见的垃圾回收器
1串行回收器
2并行回收器
3并行压缩回收器
4并发标识-清理-回收器CMS
内存管理的小技巧
1尽量使用直接量
例如需要hello字符串时采用 String str="hello"
而不是String str = new String("hello")2使用StringBuilder 和StringBuffer进行字符串连接
3尽早释放无用对象的引用
4尽量少用静态变量
5避免在经常调用的方法,循环中创建java对象
6缓存经常使用的对象
实现1使用HashMap进行缓存2直接使用某些开源的缓存项目
7尽量不要使用finalize方法
8考虑使用SoftReference 软引用,当系统内存不足时,会自动释放所应用的对象,保证程序的继续运行。
参考阅读
http://blog.youkuaiyun.com/randyjiawenjie/article/details/7551228
jvisualvm 工具在jdk的目录下 C:\jdk1.6\bin
http://developer.51cto.com/art/201203/326397.htm
http://blog.youkuaiyun.com/zsuguangh/article/details/6429592