你的服务器代码是不是用线程池开发的,如果是的话,可能的情况是没有可用的线程来处理连接的socket,那是因为你的有些socket没有能够正常地close(),导致线程一直占用着,这样非正常关闭的socket越来越多,导致线程耗尽,不能处理请求了,你最好把代码粘出来(或者主要结构),让大家看看,我以前也遇到过这样的问题,就是上面说的。[email protected]
解决方案 »
- private static String simpleName(Class<?> clazz)实参应该是什么
- 如何用文件做大容量缓冲区,实现同时读写?(类似生产者消费者)
- java有关问题
- 没分,求解,烦人的各种文档。
- 请教一个FOR循环控制语句的程序
- 不同包之间import的问题
- 求JAVA的在帮助文档!!!!!
- java编的程序为何显示的缺省字体那么小气难看?我一看就能辨认是不是JAVA编出的程序
- 从JLabe中将一张图片拖出来,放到一个Panel中,请问这能实现吗?
- 国内有哪些Java的著名+实用的网站?编辑器是IBM的VisualAge J++还是Borland的JBuilder更好一些??
- 请问能否用JAVA画出矢量图
- 简单问题大送分,请高手帮我把一个的例子源代码编译一下,所有分全部送出!!具体内容请进来观之
因为是新手,所以只能帮你顶拉,哈!
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有问题呀?