Java中的引用类型
Java中引用类型
- 强引用
Persnon p = new Person();
当Person对象不可reachable时,才被垃圾回收器回收。
- 软引用
SoftReference<Person> sr = new SoftReference<Person>(new Person());
Person p = sr.get();
当内存紧张的情况下,Person对象可能会被回收,即使它的引用计数为1
- 弱引用
WeakReference<String> w = new WeakReference<String>(new string());
String str = w.get();
只要JVM中的垃圾回收器工作,就会被回收
- 虚引用
ReferenceQueue<String> rq = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String(), rq);
ReferenceQueue:软、弱以及虚引用可以ReferenceQueue结合起来使用(构造方法传入ReferenceQueue对象),和当软引用或者是弱引用指向的对象被释放后,会将引用放在引用队列中(ReferenceQueue)。虚引用必须使用ReferenceQueue来初始化。
pr.get() 为null rq.poll为pr
虚引用其实就是形同虚设,和没引用一样。其作用就是来检查对象是否将要被回收。PhantomReference的get方法始终返回null
注:以上的sr,w, rq都强引用,指向不同对象,而在这些对象内补使用不同的引用指向我们传入的对像。
JAVA内存泄露
C中通过malloc()函数申请的内存不free()的话就会引起内存泄露。JAVA中的内存泄露是创建的对象只使用一次,今后再也不会使用,但没有将其引用计数置为0(强引用),就会发生内存泄露,示例:
public class Stack {
private Object[] elementData;
private int size = 0;
private int capacityIncrement;
public Stack(int initialCapacity){
elementData = new Object[initialCapacity];
}
public Stack(int initialCapacity, int capacityIncrement){
this(initialCapacity);
this.capacityIncrement = capacityIncrement;
}
public void push(Object object){
ensureCapacity();
elementData[size++] = object;
}
public Object pop(){
if(size == 0){
throw new RuntimeException("空栈");
}
return elementData[--size];
}
private int size(){
return size;
}
private void ensureCapacity(){
if(elementData.length == size){
Object[] oldElements = elementData;
int newLength = 0;
if(capacityIncrement > 0){
newLength = elementData.length + capacityIncrement;
}else{
newLength = (int)(elementData.length *1.5);
}
elementData = new Object[newLength];
System.arraycopy(oldElements, 0 , elementData, 0 , size);
}
}
public static void main(String[] a){
Stack stack = new Stack(10);
for(int i=0; i<10; i++)
stack.push("element" + i);
for (int i=0; i<10; i++) {
System.out.println(stack.pop());
}
}
}
在pop()函数中存在内存泄露,当弹出一个元素时,并没有将数组的引用置为null