zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    instanceof方法
    Java 实现接口计算圆柱的体积和面积并添加颜色
    Java代码执行顺序
    Java饿汉单例模式
    斐波那契数(动态规划和递归)
    Java 接口实现计算器加减乘除(字符交互界面)
    局部内部类详解_转载
    Java引用类型
    递归打印字符串
    时间复杂度
  • 原文地址:https://www.cnblogs.com/xidongyu/p/12234646.html
Copyright © 2011-2022 走看看