- java的引用
对JVM的垃圾回收机制来说,是否回收一个对象的判断标准在于:是否还有引用变量引用该对象。
当一个对象在堆内存中运行时,可以把它所处的状态分为三种:可达状态,可恢复状态,不可达状态。
引用的四类型:强引用、软引用、弱引用、虚引用。
强引用:被强引用所引用的对象绝不会被垃圾回收机制回收,因此强引用是造成java内存泄露的主要原因之一;
软引用(SoftReference):当系统内存空间足够时、不会被系统回收,当系统内存空间不足时、系统会回收该对象。通常用于内存敏感的程序;
弱引用(WeakReference):当系统垃圾回收机制运行时,不论系统的内存是否足够,总会回收该对象所占的内存;
虚引用(PhantomReference) :不能单独使用,主要用于对象被垃圾回收的状态;
- java的内存泄露
如果程序中一些java对象,他们处于可达状态,但是程序以后永远不会使用它们,那么它们所占用的内存空间也不会被回收,这即产生了内存泄露。
ArrayList中remove(int index)方法源码:
public E remove(int index) {
RangeCheck(index); //检查index索引是否越界
modCount++; //使修改次数加1
E oldValue = (E)elementData[index]; //获取被删除的元素
int numMoved = size-index-1;
if (numMoved>0) { //整体搬家
System.arraycopy(ElementData, index+1, elementData, index, numMoved);
}
// 假如没有下面这行代码,会产生内存泄露---删除一个对象,但是对象所占用的内存空间不会释放;
elementData[--size] = null; //size减一,将最后一个数组元素赋为null,让垃圾回收机制回收最后一个元素;
return oldValue;
}
- 垃圾回收机制
现行的垃圾回收器用分代的方式来采用不同的回收设计。分代的基本思路是根据对象生存时间的长短,把堆内存分为3个代:Young, Old, Permanent ;
Young:绝大多数对象不会长期被引用,在young期间就会被引用。young代采用复制算法,只需遍历可达状态的对象,对象数量少、复制成本低;
Old: Young代中对象经过数次垃圾回收依然没有被内存回收掉,垃圾回收机制会将这些对象移到Old代。Old垃圾回收执行频率无需太高,因为很少有对象死掉,
每次对Old代回收需要更长的时间来完成;因此一般采用标记压缩算法。
Permanent: 主要用于转载Class、方法等信息,默认64M,垃圾回收机制一般不会回收Permanent中的对象。
设置java虚拟机内存大小:
-Xmx:设置java虚拟机堆内存的最大容量,如: java -Xmx256m XxxClass
-Xms:设置java虚拟机堆内存的初始容量,如: java -Xms128m XxxClass
- 内存管理小技巧
1. 尽量使用直接量
在使用Byte Short Integer Long Float Double Boolean String等包装类时,尽量避免使用new来创建对象,应采用直接量来创建他们;
2. 使用StringBuilder和StringBuffer进行字符串连接
3. 尽早释放无用对象的引用
方法局部引用变量所引用的对象会随着方法结束而变成垃圾,因此 大部分程序无须将局部、引用变量显示设为null;
4. 尽量少使用静态变量
静态变量被存在Permanent代里,生命周期与类同步。
5. 避免在经常调用的方法、循环中创建java对象
6. 缓存经常使用的对象
7. 考虑使用SoftReference