前些天紧急出版本,发现一个内存泄漏问题,程序每次注销都会有大量的对象没有释放,在
注销登陆成功后,又会重新生成一个相同的对象。这样,在做界面自动化测试的过程中,系统
频繁注销,登陆,再注销。这样如此反复多次,会必然导致java这个进程的内存溢出OutOfMemory。
拿到问题,用JProfile把程序跑起来,查到具体泄漏的对象,然后进行详细的分析。
发现两个地方存在严重的泄漏:
1 某对象在创建,初始化的过程会创建一个线程,这个线程专门处理和计算机串口的通讯。
代码如下:package example;/*** @author zLan1028** TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates*/public class MemoeryTest{
public static void main(String[] args){MemoeryTest test = new MemoeryTest();
test.init();
test = null;
//do other something}
public void init(){thread.start();}
private Thread thread = new BasicThread ();
boolean exit = false;
class BasicThread extends Thread(){List lstData = new LinkedList();
public void run(){while(!exit){synchronized(lstData){if (lstData.isEmpty()){lstData.wait();}writeDataToSerialPort((String)lstData.removeFirst());}}}
咋一看,应该会,这个对象已经没有其它引用存在。其实不然,因为这个对象中创建了一个内部类。
而在java中,内部类会自动获得一个对外部类的对象引用,而在释放test对象时,没有去把它内部创建的线程对象,
所以这个线程对象在程序退出前会一直存在,所以它会一直保持对外部test对象的引用,这样,每创建一个MemoeryTest
对象,都会存在一个线程对象泄漏,而且一个MemoeryTest对象泄漏。这样时非常危险的。
如果只对这个对象进行初始化,而在程序注销时没有对创建的线程资源回收,则这个问题可以避免。
代码如下:在MemoeryTest 对象中增加一个 public void close()方法,在每次释放MemoeryTest 对象时,主动调用close方法释放资源。