最近给公司写了一个小型数据处理服务器,具备以下功能:
接收多个设备TCP连接
对于每个连接,独自接收客户端发送来的字节数组数据进行处理(存储到数据库)
以下是具体实现(采用多线程):
首先启动一个Swing窗体,点击启动按钮开启服务器(开启服务端口监听,while(true)循环中执行ServerSocket.accept())
定义一个数据处理线程类DataSocketThread(后面简写dst)(包含ServerSocket.accept()得到的Socket)
每当ServerSocket.accept()到Socket就开启一个包含此Socket的dst线程
dst线程run方法中也是一个while(flag)的循环中通过Socket的InputStream不停地read,期间通过多种方式(设置read超时、异常处理等方式设置flag=false来结束线程)
项目分为许多个类和包
以上内容大致一看,以下是存在问题:
项目运行在win7 64位 jdk-7u80-windows-i586(32位),运行参数java -Xmx200m -Xms20m com.i5.start.Start
按照运行参数设置,java虚拟机内存不会超过200M,但实际运行会超过200M,不只是一点点,目前测试最高到了600多M,也没报内存溢出异常。难道我设置的不正确吗?但之前用一个小测试程序测试时达到指定内存会报内存溢出异常,到了这里为什么就不报了?(测试程序多线程也测试过)
小测试程序为
import java.util.ArrayList;
public class TestCrash implements Runnable {
public static void main(String[] args) throws InterruptedException {
TestCrash tc = new TestCrash();
new Thread(tc).start();
ArrayList<TestCrash> arr = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
arr.add(new TestCrash());
if (i % 200 == 0) {
System.out.println(i);
}
}
}
@Override
public void run() {
ArrayList<TestCrash> arr = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
arr.add(new TestCrash());
if (i % 200 == 0) {
System.out.println(i);
}
}
}
}
同时在运行这个小程序的时候,如果不设置内存运行参数,那么占用内存会很快增长,这时我的服务器程序占用内存会逐渐减小,直到几M,这说明服务器程序的GC开始工作,而且程序本身也并没有不释放资源。
问:
1、在不设置java虚拟机运行内存的情况下,程序占内存会越来愈大,最后在win7下停止工作(可能是操作系统强制java虚拟机停止)
2、设置了运行内存,但为什么总会超,既不及时回收又不报内存溢出异常,最终还是会被操作系统终止
请问怎样解决??(表达能力有限,童鞋们凑合看哈~~~)