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都强引用,指向不同对象,而在这些对象内补使用不同的引用指向我们传入的对像。

参考文章1 参考文章2

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

posted @ 2020-01-26 19:15  被罚站的树  阅读(213)  评论(0编辑  收藏  举报