`

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[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中对原因的描述:

 

写道
The reason is that the java.lang.Thread class adds the thread to the thread group in the init() method, which is called from the constructor. It removes the thread from the thread group in the exit() method, which is only called if the thread is run. So if the thread is never run, the thread group still has a reference to the Thread and it will never be garbage collected. And of course any objects which the thread has references to will in turn not be garbage collected.
 

 

 

分享到:
评论

相关推荐

    jdk1.4.2_08

    jdk1.4.2_08.rar 这个是一jdk压缩包,解压就可以用了

    jdk1.4.2_06

    早起的jdk1.4.2_06 网上资源不多了

    jdk1.4.2_04.rar

    jdk1.4.2_04.rar老式,专业品质!

    jdk1.4.2_07

    较老版本jdk1.4.2_07,留着备用

    解决-BASH: /HOME/JAVA/JDK1.8.0_221/BIN/JAVA: 权限不够问题

    以上所述是小编给大家介绍的解决-BASH: /HOME/JAVA/JDK1.8.0_221/BIN/JAVA: 权限不够问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对软件开发网网站的支持! ...

    j2sdk1.4.2_09.zip

    最近在项目中遇到了需要使用旧版本的jdk1.4,终于找到,提供给需要使用老版本jdk的朋友,适合配合tomcat5使用。

    非安装jdk1.4.2.rar

    非安装版的jdk1.4.2,解压到磁盘即可运行,不需要安装

    jdk1.8.0_231

    配置环境变量,vi /etc/profile,在文件最后添加配置 JAVA_HOME=/usr/local/java/jdk1.8.0_231/ JRE_HOME=/usr/local/java/jdk1.8.0_231/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_...

    j2sdk1.4.2_07.zip

    j2sdk1.4.2_07.zip 最稳定1.4JDK

    jdk1.8.131

    java运行环境jdk1.8.0_131,windows下64位操作系统,添加环境变量JAVA_HOME:C:\Program Files\Java\jdk1.8.0_131 classpath:.,C:\Program Files\Java\jdk1.8.0_131jre\lib\rt.jar,C:\Program Files\Java\jdk1.8.0_131\...

    jdk1.4.2.zip

    国内现在被禁的越来越厉害了,Oracle官网很难访问并下载了,提供早期JDK版本供需要的人使用。

    jdk1.8.0_333.x86_64-linux

    linux(x86_64)下的jdk压缩包,版本为 1.8.0_333。附带安装教程。 1、将jdk压缩包解压到指定目录(如:/usr/local/java) 2、添加环境变量(sudo vi ~/.bashrc) export JAVA_HOME=/usr/local/java/jdk1.8.0_333 ...

    Bea JRockit j2sdk 1.4.2_05 win32

    号称业界最快java虚拟机,可用于规避perm gen异常。本版本为bea被oracle收购之前的版本。

    centos安装jdk1.8时出现没有/lib/ld-linux.so.2:这个文件的原因分析

    -bash: /usr/local/jdk/jdk1.8.0_181/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory 安装完后 java -version 查看版本出现: 原因是:没有那个文件或目录,找了很久发现需要...

    jdk1.4.2免安装版

    jdk1.4老资源,留一份自用。JDK1.4.2 无需安装,解压后直接使用。

    Java_jdk1.8.0_241 环境变量

    Java_jdk1.8.0_241 环境变量

    jdk1.4.2源代码

    jdk1.4.2源代码............

    Windows版本JDK:jdk1.8.0_192_x64.zip

    1. 直接解压,比如解压到:D:\Dev\Java 2. 配置环境变量:我的电脑 -&gt;右键菜单 -&gt;属性 -&gt;高级系统设置 -&gt;环境变量 -&gt;用户变量中Path -&gt;编辑 -&gt;新增:D:\Dev\Java\jdk1.8.0_192\bin

    JAVA jdk1.8.0_101绿色版本

    JAVA jdk1.8.0_101绿色版本 系统变量→新建 JAVA_HOME 变量 。 变量值填写jdk的安装目录(本人是 C:\java\jdk1.8.0_101 ) 系统变量→寻找 Path 变量→编辑 在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; ...

    jdk1.7.0_80

    jdk1.7.0_80直接解压就能用。jdk1.7.0_80直接解压就能用。

Global site tag (gtag.js) - Google Analytics