我们的系统有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[0].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 memory
public class AliveTest {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
Runtime r = Runtime.getRuntime();
for (int i = 1;; i++) {
//OK
new 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[10000];
public void run() {
a[0] = 1;
}
}
Bug4533087中对原因的描述: