Java线程: New他就Start他 (遇见JDK1.4.2_04以前的一个bug)
我们的系统有OutOfMemory现象, Liu同学最近又发现了一个原因:Sun JDK 1.4.2_04版本(含以前)的bug,我们系统另一个OOM的原因参见:Derby: Out Of Memory & Update
对与sun的这个bug我以前一无所知, 有必要记录下来, 学习一下.
Bug现象:
一个线程如果只是new, 而没有start(), 那么该线程不会被垃圾回收,
我们系统使用的一个jar包(日方提供的), 里面有一个api, 功能是去网络上通过snmp协议取一个mib值,
反编译过来发现他有这种"只是new一个线程,并没有start"的问题,
于是系统持续运行就导致了OutOfMemory
另:该bug在jdk5,6 上测试,已经修正.
(艾~这么久的bug我们也能遇到,关于使用底版本的原因我就不另作点评了, 否则又要郁闷了...此处省略1W字^^)
下面这两个链接
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4533087
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508232
上面这两个链接已经将bug描述得很清楚了, 但是我害怕以后我会找不到这两个链接,
因为现在一些bea的东西我就已经找不到地方了, 所以见bug原因和测试代码抽出如下:
Bug4533087的测试代码:
class ThreadLeak {static MyThread t;public static void main(String[] args) {if ((args.length > 0) && args.equals("run")) {System.out.println("Creating and running 10,000 threads...");for (int i = 0; i < 10000; i++) {t = new MyThread(true);}} else {System.out.println("Creating 10,000 threads, but not running them...");for (int i = 0; i < 10000; i++) {t = new MyThread(false);}}System.out.println("Running garbage collector...");System.gc();System.out.println("Done.Heap size is "+ (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));}}class MyThread implements Runnable {Thread t;public MyThread(boolean bRun) {t = new Thread(this, "MyThread");if (bRun) {t.start();}}public void run() {/* NO-OP */}}
Bug4508232的测试代码:
package thread;// AliveTest.java: program to test theory that Threads which are not started// are not garbage collected// - We create "T" Threads but don't "start" them.The output shows:// a)that creation is fast (compared to -starting- Threads)// b)that memory is garbage collected// c)the Thread ACTIVE count always increases// d) eventually we run out of memorypublic class AliveTest {public static void main(String[] args) {long t1 = System.currentTimeMillis();Runtime r = Runtime.getRuntime();for (int i = 1;; i++) {//OKnew T().start();//OutOfMemory//new T();if (i % 100 == 0) {System.out.println("Threads created: " + i + ", t: "+ (System.currentTimeMillis() - t1) / 1000+ " sec, activeCount: " + Thread.activeCount()+ ", Free mem:" + r.freeMemory() / 1000 + " K");}}}}class T extends Thread {int[] a = new int;public void run() {a = 1;}}
Bug4533087中对原因的描述:
<div class="quote_title"> 写道
页:
[1]