Java中引用类型
- 强引用
Persnon p = new Person();
当指向Person对象的引用计数为0时,Person对象才能被垃圾回收器回收。
- 软引用
SoftReference
获取软引用对象Person p = sr.get();
当内存紧张的情况下,Person对象可能会被回收,即使它的引用计数为1
- 弱引用
WeakReference
获取软引用对象String str = w.get();
只要JVM中的垃圾回收器工作,就会被回收
- 虚引用
引用队列:当软引用或者是弱引用指向的对象被释放后,会将引用放在引用队列中(ReferenceQueue)。
虚引用是先将引用加入队列中再释放对象。
ReferenceQueue
PhantomReference
//pr.get() 为null rq.poll为pr
虚引用其实就是形同虚设,和没引用一样。其作用就是来检查对象是否将要被回收。并且没有get()方法来获取传入的对象。
注:以上的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
来源:https://www.cnblogs.com/xidongyu/p/12234646.html