看了你的代码,给两点建议: 1、对于数据库联接的使用,尽量把connection关掉,我看你好像用的是静态变量 2、你的server看了很简单,从你的代码上来看好像没错。能不能启一个监控进程,它的功能就是把在jvm中的进程都打印出来。 public void run() { int count=0; while(run) { //列出所有线程 int total=Thread.activeCount(); Thread[] totalThread=new Thread[total]; int length=Thread.enumerate(totalThread);
package common;public class ListResources extends Thread {
//变量部分 public boolean run=true;
public ListResources() { } public void run() { int count=0; while(run) { //列出所有线程 int total=Thread.activeCount(); Thread[] totalThread=new Thread[total]; int length=Thread.enumerate(totalThread);
最新的情况: 应该和内存无关! 我想还是SOCKET的问题,我把可以关掉的都关掉了,最后还把用到的变量全部设为null了,在一个线程中检测线程数和内存,线程里用一个循环,每执行一次睡眠30秒,在循环打印出内存大小和线程数,并执行一次System.gc()运行时freeMemory最大时为3M多,最少时一M多, 后来死掉了,那时的内存是有2M多的.代码和出错时的现象: 服务器: memoryTest memory=new memoryTest(); //检测线程数和内存,并且执行System.gc() Thread mythread = new Thread(memory); mythread.start(); ServerSocket s = new ServerSocket(ServerPort); System.out.println("listening..."); while (true) { Socket socket = s.accept(); socket.getInetAddress().getHostAddress(); listenSocket server = new listenSocket(socket); Thread thread = new Thread(server); thread.start(); } 线程: public void run() { System.out.println("thread start"); try { InputStream is = socket1.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); char c[] = new char[136]; int c1 = 0; int jump_out = 10; String tmp_jylb = null; while (c1 < 136) { c[c1] = (char) br.read(); c1++; if (c1 == jump_out) { break; } if (c1 == 5) { tmp_jylb = String.valueOf(c, 0, 4); if (tmp_jylb.equalsIgnoreCase("0400")) { jump_out = 37; } else if (tmp_jylb.equalsIgnoreCase("0500")) { jump_out = 37; } else if (tmp_jylb.equalsIgnoreCase("0600")) { jump_out = 84; } else { jump_out = 136; } } } System.out.println(c); //打印出得到的字符 正常运行时,应该是打印"thread start"和打印从socket得到的字符,由于每次mythread线程运行时刚好处于socket空闲状态,所以每次打印出的socket数时都是3,出错时情况为:thread start thread count 4 freememory 2000000 totalmemory 8000000也就是说socket线程在打印“thread start”和打印接收到的数据c之间时停止了反应,然后到了mythread线程执行的时间,这时的线程数已经是4了,这时客户端再怎么发数据,也得不到响应的了我这个SOCKET是接收定长数据的,由于客户端是用C写的,他们好象没有结束符的,所以我不能一行一行读,只能一个一个字符读,当客户端发送的数据太少时,服务器端由于一直在等待,所以客户端要很久才能得到反应,但我做过测试,连续发送几个很短的数据,虽然等待时间比较长,但都能分别得到回应,所以我搞不懂这里到底是怎么回事另外,会不会发生这样的情况:原来的问题是由于内存耗尽,本来通过关闭一些资源,问题已经解决,但是由于执行了System.gc(),结果在线程执行在System.out.println("thread start") 和System.out.println(c);之间某个位置时,把正在使用的某个变量当垃圾收走了? 呵呵,应该没有那么弱智。
javafaq2004(农村干部瞎忙活)
等待处理的连接数量。
你的意思是socket服务器等待处理的连接数量吗? 一般能处理多少个连接,如何设置? 谢谢!
第一,有关线程数目和内存大小的问题: jvm启动一个java应用会有内存限制,如果要自定义内存,开仪考虑使用 java -X 查看特殊指令,列表如下: -Xmixed mixed mode execution (default) -Xint interpreted mode execution only -Xbootclasspath:<directories and zip/jar files separated by ;> set search path for bootstrap classes and resources -Xbootclasspath/a:<directories and zip/jar files separated by ;> append to end of bootstrap class path -Xbootclasspath/p:<directories and zip/jar files separated by ;> prepend in front of bootstrap class path -Xnoclassgc disable class garbage collection -Xincgc enable incremental garbage collection -Xloggc:<file> log GC status to a file with time stamps -Xbatch disable background compilation -Xms<size> set initial Java heap size -Xmx<size> set maximum Java heap size -Xss<size> set java thread stack size -Xprof output cpu profiling data -Xrunhprof[:help]|[:<option>=<value>, ...] perform JVMPI heap, cpu, or monitor profiling -Xdebug enable remote debugging -Xfuture enable strictest checks, anticipating future default -Xrs reduce use of OS signals by Java/VM (see documentation) -Xcheck:jni perform additional checks for JNI functions 正是由于这些的限制可以保证Java无论怎样也不会死机,包括死循环。ServerSocket有个最大限制,默认是多少根据平台的不一样而不同,如果需要特别指定,可以在其构造函数的第二个参数设置。
由于我没有这方面的开发经验,故贴出JDK中的相关说明如下: ServerSocket public ServerSocket(int port, int backlog) throws IOExceptionCreates a server socket and binds it to the specified local port number, with the specified backlog. A port number of 0 creates a socket on any free port. The maximum queue length for incoming connection indications (a request to connect) is set to the backlog parameter. If a connection indication arrives when the queue is full, the connection is refused. If the application has specified a server socket factory, that factory's createSocketImpl method is called to create the actual socket implementation. Otherwise a "plain" socket is created. If there is a security manager, its checkListen method is called with the port argument as its argument to ensure the operation is allowed. This could result in a SecurityException. The backlog argument must be a positive value greater than 0. If the value passed if equal or less than 0, then the default value will be assumed. Parameters: port - the specified port, or 0 to use any free port. backlog - the maximum length of the queue. Throws: IOException - if an I/O error occurs when opening the socket. SecurityException - if a security manager exists and its checkListen method doesn't allow the operation. See Also: SocketImpl, SocketImplFactory.createSocketImpl(), setSocketFactory(java.net.SocketImplFactory), SecurityManager.checkListen(int)
因为是新手,所以只能帮你顶拉,哈!
UP
1、对于数据库联接的使用,尽量把connection关掉,我看你好像用的是静态变量
2、你的server看了很简单,从你的代码上来看好像没错。能不能启一个监控进程,它的功能就是把在jvm中的进程都打印出来。
public void run() {
int count=0;
while(run)
{
//列出所有线程
int total=Thread.activeCount();
Thread[] totalThread=new Thread[total];
int length=Thread.enumerate(totalThread);
for(int i=0;i<length;i++)
{
count++;
log.info(totalThread[i].getName());
}
log.info("freeMemory:"+Runtime.getRuntime().freeMemory());
log.info("maxMemory:"+Runtime.getRuntime().maxMemory());
log.info("totalMemory:"+Runtime.getRuntime().totalMemory());
log.info("Thread list("+count+"):");
count=0;
}
}
这样来监控一下结果,看看是不是进程分配满了
那是因为你的有些socket没有能够正常地close(),导致线程一直占用着如果真是这样的话就好解释了,但在什么情况下 socket会不能正常地close()? 从程序看好象就算有一些资源没有被释放掉,线程也是结束了的吧?我现在发现在某些地方,statement 和 resultset没有被关闭, 会不会是这个原因呢? 在程序刚写好时,statement是全部都不关闭的,这样,运行了一段时间后,就会出错,提示已经超过最大的光标数,现在虽然没有完全关闭statement,但已经不再出这个错了,所以我一直没在意,以为不会是这个原因我说的"现在虽然没有完全关闭statement",意思是我当初改了程序,有些地方加了statement.close(),有时地方则没有动
//变量部分
public boolean run=true;
public ListResources()
{
} public void run() {
int count=0;
while(run)
{
//列出所有线程
int total=Thread.activeCount();
Thread[] totalThread=new Thread[total];
int length=Thread.enumerate(totalThread);
for(int i=0;i<length;i++)
{
count++;
log.info(totalThread[i].getName());
}
log.info("freeMemory:"+Runtime.getRuntime().freeMemory());
log.info("maxMemory:"+Runtime.getRuntime().maxMemory());
log.info("totalMemory:"+Runtime.getRuntime().totalMemory());
log.info("Thread list("+count+"):");
count=0;
}
}
public void close() {run=false;}
}
我把代码贴出来。
市你server的一个进程
像resultset,statement,conneciton.socket等等资源
你说“发现线程数是不变的”不知道什么意思?怎么叫不变呢?应该是有一个访问就该多一个三。
你说“那怎样设置一个JAVA程序可用的内存呢?我想设大一些”我觉得不是根本办法,除非你的程序启动时就报内存溢出。当然你的访问量太大时也要增大jvm的内存。
把不用的变量都设置成null这样可以加快垃圾收集
服务器:
memoryTest memory=new memoryTest(); //检测线程数和内存,并且执行System.gc()
Thread mythread = new Thread(memory);
mythread.start();
ServerSocket s = new ServerSocket(ServerPort);
System.out.println("listening...");
while (true) {
Socket socket = s.accept();
socket.getInetAddress().getHostAddress();
listenSocket server = new listenSocket(socket);
Thread thread = new Thread(server);
thread.start();
}
线程:
public void run() {
System.out.println("thread start");
try {
InputStream is = socket1.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
char c[] = new char[136];
int c1 = 0;
int jump_out = 10;
String tmp_jylb = null;
while (c1 < 136) {
c[c1] = (char) br.read();
c1++;
if (c1 == jump_out) {
break;
}
if (c1 == 5) {
tmp_jylb = String.valueOf(c, 0, 4);
if (tmp_jylb.equalsIgnoreCase("0400")) {
jump_out = 37;
}
else if (tmp_jylb.equalsIgnoreCase("0500")) {
jump_out = 37;
}
else if (tmp_jylb.equalsIgnoreCase("0600")) {
jump_out = 84; }
else {
jump_out = 136;
}
}
}
System.out.println(c); //打印出得到的字符
正常运行时,应该是打印"thread start"和打印从socket得到的字符,由于每次mythread线程运行时刚好处于socket空闲状态,所以每次打印出的socket数时都是3,出错时情况为:thread start
thread count 4
freememory 2000000
totalmemory 8000000也就是说socket线程在打印“thread start”和打印接收到的数据c之间时停止了反应,然后到了mythread线程执行的时间,这时的线程数已经是4了,这时客户端再怎么发数据,也得不到响应的了我这个SOCKET是接收定长数据的,由于客户端是用C写的,他们好象没有结束符的,所以我不能一行一行读,只能一个一个字符读,当客户端发送的数据太少时,服务器端由于一直在等待,所以客户端要很久才能得到反应,但我做过测试,连续发送几个很短的数据,虽然等待时间比较长,但都能分别得到回应,所以我搞不懂这里到底是怎么回事另外,会不会发生这样的情况:原来的问题是由于内存耗尽,本来通过关闭一些资源,问题已经解决,但是由于执行了System.gc(),结果在线程执行在System.out.println("thread start") 和System.out.println(c);之间某个位置时,把正在使用的某个变量当垃圾收走了? 呵呵,应该没有那么弱智。
等待处理的连接数量。
你的意思是socket服务器等待处理的连接数量吗? 一般能处理多少个连接,如何设置? 谢谢!
jvm启动一个java应用会有内存限制,如果要自定义内存,开仪考虑使用
java -X
查看特殊指令,列表如下:
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xrunhprof[:help]|[:<option>=<value>, ...]
perform JVMPI heap, cpu, or monitor profiling
-Xdebug enable remote debugging
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni perform additional checks for JNI functions
正是由于这些的限制可以保证Java无论怎样也不会死机,包括死循环。ServerSocket有个最大限制,默认是多少根据平台的不一样而不同,如果需要特别指定,可以在其构造函数的第二个参数设置。
ServerSocket
public ServerSocket(int port,
int backlog)
throws IOExceptionCreates a server socket and binds it to the specified local port number, with the specified backlog. A port number of 0 creates a socket on any free port.
The maximum queue length for incoming connection indications (a request to connect) is set to the backlog parameter. If a connection indication arrives when the queue is full, the connection is refused. If the application has specified a server socket factory, that factory's createSocketImpl method is called to create the actual socket implementation. Otherwise a "plain" socket is created. If there is a security manager, its checkListen method is called with the port argument as its argument to ensure the operation is allowed. This could result in a SecurityException. The backlog argument must be a positive value greater than 0. If the value passed if equal or less than 0, then the default value will be assumed. Parameters:
port - the specified port, or 0 to use any free port.
backlog - the maximum length of the queue.
Throws:
IOException - if an I/O error occurs when opening the socket.
SecurityException - if a security manager exists and its checkListen method doesn't allow the operation.
See Also:
SocketImpl, SocketImplFactory.createSocketImpl(), setSocketFactory(java.net.SocketImplFactory), SecurityManager.checkListen(int)
freememory 2000000
totalmemory 8000000
memoryTest memory=new memoryTest(); //检测线程数和内存,并且执行System.gc()
Thread mythread = new Thread(memory);
mythread.start();这个线程里面啊
int count=0;
while(true)
{
int total=Thread.activeCount();
System.out.println("thread count"+total);
System.out.println("freeMemory:"+Runtime.getRuntime().freeMemory());
System.out.println("totalMemory:"+Runtime.getRuntime().totalMemory()); Thread.sleep(30000);
}
能否详细说说?
调用gc是不会有什么问题的,有影响的是在调用gc时所有进程会挂起,但gc完后就正常了。
你的问题真得很奇怪,可能是没有吧源代码看完分析得不透彻。
可不可以这样,你让你的listenSocket中的run就两句话:
public void run() {
System.out.println("start");
System.out.println("end");
}
看看会怎样?
但理应listenSocket进程出问题不会影响到server进程才对,不清楚了,你试了再看。
thread count 4
freememory 2000000
totalmemory 8000000后不管多长时间,mythread也不会在屏幕上打印任何信息,是不是JDK有问题呀?