当前位置:天才代写 > tutorial > JAVA 教程 > Effective Java (6) 如何消除逾期的工具引用

Effective Java (6) 如何消除逾期的工具引用

2017-11-02 08:00 星期四 所属: JAVA 教程 浏览:66

一、引言

许多人大概在想这么一个问题:Java有垃圾接纳机制,那么还存在内存泄露吗?谜底是必定的,所谓的垃圾接纳GC会自动打点内存的接纳,而不需要措施员每次都手动释放内存,可是假如存在大量的姑且工具在不需要利用时并没有打消对它们的引用,就会吞噬掉大量的内存,很快就会造成内存溢出。

二、Java的垃圾接纳机制

Java中的工具是在堆中分派,工具的建设有2中方法:new可能反射。工具的接纳是通过垃圾收集器,JVM的垃圾收集器简化了措施员的事情,可是却加重了JVM的事情,这是Java措施运行稍慢的原因之一,因为GC为了能正确释放工具,必需监控每一个工具的运行状态,包罗工具的申请、引用、被引用、赋值等,GC都要举办监控,监控工具的状态是为了越发精确、实时地释放工具,而释放工具的基础原则就是该工具不再被引用。

三、Java中的内存泄露

内存泄露的工具有以下两个特点:

① 这些工具是可达的,即在有向图中存在通路可以与其相连。

② 这些工具是无用的,即措施今后都不会再利用这些工具。

public class Stack {  
    private final static int MAX_ATTRIBUTE = 10;  
    private Object[] arr;  
    private int index = 0;;  
      
    public void push(Object obj) {  
        if (index > 9)  
            throw new IllegalArgumentException();  
        arr[index] = obj;  
        index++;  
    }  
      
    public Stack() {  
        arr = new Object[MAX_ATTRIBUTE];  
    }  
      
    public Object pop() {  
        if (index < 0)  
            throw new IllegalArgumentException();  
        return arr[--index];  
    }  
}

这个措施哪里产生了内存泄露呢?假如一个栈先增长然后收缩,那么从栈中弹出来的工具将不会被当做垃圾接纳,纵然利用栈的措施不再引用这些工具,它们也不会被接纳,因为栈内部维护这对这些工具的逾期引用。

public Object pop() {    
    if (size == 0)    
        throw new EmptyStackException();    
    Object result = elements[--size];    
    elements[size] = null; //Eliminate obsolete reference       
    return result;    
}

查察本栏目

办理步伐:只要一个元素被弹出栈,那么就将它的引用置为空,GC就会接纳。

四、常见的内存泄露

① 像HashMap、Vector等静态荟萃类的利用最容易引起内存泄露,因为这些静态变量的生命周期与应用措施一致。

Vector<Object> vector = new Vector<Object>(10);   
for (int i = 1; i < 100; i++) {  
    Object obj = new Object();   
    vector.add(obj);  
    obj = null;  
}

把工具放入Vector中,假如仅仅释放引用自己,但Vector仍然引用该工具,那么这个工具对GC来说是不行接纳的,假如要接纳它,最简朴的服务是将Vector工具设为null。

② 在Java措施中,我们常常要和监听器打交道,凡是挪用诸如addXXXListener()等要领来增加监听器,但往往健忘删除这些监听器,从而增加了内存泄漏的时机。

③ 利用毗连池时,除了要显式地封锁毗连,还必需显式地封锁Resultset和Statement工具。不然会造成大量的这些工具无法释放,从而引起内存泄露。

 

    关键字:


天才代写-代写联系方式