论坛首页 入门技术论坛

Linux下的Socket异常导致OutOfMemory,定位结果Linux下JVM Bug。

浏览 3271 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-09-25  
现网出现一个问题,Client访问我们的接入服务器A,A将请求转给服务器B(Http请求,使用HttpURLConnection实现);某天,B服务器突然宕机,Client在登录的过程中,经常需要访问B,B宕机一段时间后,A也报出OutOfMemoryError。

这个问题定位了很久,开始以为我们的代码有问题,以为IO流没有关闭,打开GC日志进行压力测试,没有发现堆内存问题。
但JVM还是宕机。

之后,在Linux下,我们模拟现网的情况,访问另一机器的不存在的端口,在大并发的情况下,Xmx设为1024m,大概12个小时,JVM会OutOfMemory;如果将Xmx设为1700m,不到一小时,JVM就会OutOfMemory;

HttpURLConnection是基于TCP实现的,所以为了进一步验证,我把HttpURLConnection改成了Socket,同样访问另一机器的不存在的端口,也会出现同样的问题;

在Windows下,我也经过两样的验证,跑了10多个小时,没有出现异常,因此,可以断定,Linux下的JVM 1.5实现有Bug。Socket实现是依赖本地的实现的,Linux下的Socket实现有Bug,导致JNI内存溢出。

-----------------------------

希望遇到同样问题的朋友,可以少走弯路。
   发表时间:2008-09-25  
给出代码,socket的实现有差异,但不至于访问不在监听的端口就出现OOM。我猜测你们的问题在于打开的socket超过了进程允许的最大文件句柄数,也就是说没有正常关闭出现异常的socket或者HttpURLConnection
0 请登录后投票
   发表时间:2008-09-25  
嘿嘿,明显是打开的文件句柄过多造成的JVM进程crash。
0 请登录后投票
   发表时间:2008-09-26  
感谢上面两位的回复。
此处我要说明,你们说的问题绝对不存在,如果有你们说的异常,我早就可以定位出问题来了。

另外,同样的代码在Windows下为什么不出错?

----- 测试代码如下:
使用 java -Xms1024m -Xmx1024m Main启动下面的代码,在Linux下测试,
如果将 -Xmx1500m 或者更大,JVM死得更快。


import java.io.IOException;
import java.net.Socket;

public class Main implements Runnable {
	public static void main(String[] args) {
		int threads = 500;
		try {
			threads = Integer.parseInt(args[0]);
		} catch (Exception e) {
		}

		for (int i = 1; i <= threads; i++) {
			new Thread(new Main()).start();
		}
	}

	public void run() {
		while (true) {
			socketConnect();
		}
	}

	public void socketConnect() {
		Socket socket = null;
		try {
			socket = new Socket("127.0.0.1", 59998); // 请保证该端口59998没有Socket在监听。
		} catch (IOException e) {
			// e.printStackTrace();
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					// 不作处理
				}
			}
		}
	}
}
0 请登录后投票
   发表时间:2008-09-27  
可以肯定是JDK的Bug,测试的JDK版本为Linux JDK1.5_03

我使用JDK1.5_06后,没有问题。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics