假设我们有套接字客户端,它正在执行读写操作。有两个线程执行发送和接收操作(请求发送方/响应接收方)。这些线程一一运行Junit测试用例(像一些压力测试,简单查询)。对于我的情况,我正在运行客户端,它将在 DB 端和它自己的端之间建立套接字通信。在这个逻辑中,请求发送者线程将请求发送到DB端(将请求写入套接字),接收者线程通过读取套接字接收响应(从套接字读取响应)。实际问题随机出现。假设如果请求发送者线程发送请求,响应接收者尚未收到来自发送请求的另一端的响应。
byte[] ofsRes = new byte[size];
这部分会收到 jVm Out of memory 错误发生。我怀疑同时读取响应接收器线程会导致此问题,在堆中分配更多大小的字节对象。
从套接字读取数据
int size = dataInputStream.readInt();
您能否帮助任何人解决内存不足错误/可能是线程并发问题,即使我使用了同步。但没有用。如果您需要任何东西,请告诉我。
private static class ResponseReceiver implements Runnable {
private InputStream _in;
private List<String> _responses = new ArrayList<String>();
private int _expectedCount;
private volatile boolean _finished = false;
public ResponseReceiver(InputStream in, int expectedCount) {
_in = in;
_expectedCount = expectedCount;
}
public List<String> getResponses() {
return _responses;
}
public void run() {
DataInputStream dataInputStream = new DataInputStream(_in);
try {
while (true) {
_logger.info("_responses.size() >= _expectedCount : -> " + (_responses.size() >= _expectedCount) +
" : " + "_responses.size() -> " + _responses.size() + " : " + "_expectedCount -> " + _expectedCount);
if (_responses.size() >= _expectedCount) {
_finished = true;
return;
}
int size = dataInputStream.readInt();
_logger.info("size captured : " + size);
if (size > 0) {
int readSize = 0;
_logger.info( " ofsRes Creating with this size : " + size);
**byte[] ofsRes = new byte[size];**
while (size > 0) {
_logger.info( " Buffer Creating with this size : " + size);
byte[] buffer = new byte[size];
int bufferSize = _in.read(buffer);
_logger.info( " Reading data created Buffer Size : " + bufferSize);
System.arraycopy(buffer, 0, ofsRes, readSize,
bufferSize);
readSize += bufferSize;
_logger.info( " readSize (readSize += bufferSize): " + readSize);
size -= bufferSize;
_logger.info( " size (size -= bufferSize): " + size);
}
_responses.add(new String(ofsRes));
_logger.info("ofsRes added..");
}
}
} catch (IOException e) {
throw new RuntimeException("Error reading data from socket: "
+ e.getMessage());
}
}
}
执行顺序的跟踪:
2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:_responses.size() >= _expectedCount:-> false:_responses.size()->905:_expectedCount- > 1000 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:捕获的大小:1529 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test。 socket.SocketClient$ResponseReceiver 运行信息:ofsRes 使用此大小创建:1529 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:缓冲区创建此大小:1529 年 5 月 27 日, 2013 年 11:45:13 AM com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:读取数据已创建缓冲区大小:1529 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket .SocketClient$ResponseReceiver 运行 INFO: readSize (readSize += bufferSize): 1529 May 27, 2013 11:45:13 AM com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:大小(size -= bufferSize):0 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver运行信息:ofsRes 添加.. 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行 信息:_responses.size() >= _expectedCount:-> false:_responses.size()-> 906:_expectedCount-> 1000
假设一个测试用例正在运行等待响应 * ** * ** (906)
2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.SocketClientTest ofsmlEnqSimpleTest13 信息:OFSML 13 简单查询测试正在进行中...
另一起案件开始
2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient 发送信息:System.currentTimeMillis():-> 1369635313336:System.currentTimeMillis()- startTime:-> 0:超时-> 5000 :startTime -> 1369635313336:条件:true 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:_responses.size() >= _expectedCount:-> false:_responses。 size() -> 0 : _expectedCount -> 1
*假设可能会有不同的读取*
2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行 信息:捕获的大小:195399 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket。 SocketClient$ResponseReceiver 运行 信息:捕获的大小:1195528239 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行 信息:ofsRes 使用此大小创建:195399 2013 年 5 月 27 日 11:45 :13 AM com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:ofsRes 使用此大小创建:1195528239 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:使用此大小创建缓冲区:195399 线程“Thread-22”中的异常 java.lang.OutOfMemoryError:Java 堆空间 在 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver.run(SocketClient.java:147) 在 java.lang.Thread.run(Thread.java:662) 2013 年 5 月 27 日上午 11:45:13 com。 xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:读取数据创建缓冲区大小:759 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:readSize (readSize += bufferSize):759 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:大小(大小 -= bufferSize):194640 2013 年 5 月 27 日 11:45:13 AM com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:使用此大小创建缓冲区:194640 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:读取数据创建缓冲区大小:1533 May 27, 2013 11:45:13 AM com.xxx.tocf.test.socket。SocketClient$ResponseReceiver 运行信息:readSize(readSize += bufferSize):2292 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:大小(大小 -= bufferSize):193107 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test.socket.SocketClient$ResponseReceiver 运行信息:使用此大小创建缓冲区:193107 2013 年 5 月 27 日上午 11:45:13 com.xxx.tocf.test .socket.SocketClient$ResponseReceiver 运行信息:读取数据创建缓冲区大小:767SocketClient$ResponseReceiver 运行信息:读取数据创建缓冲区大小:767SocketClient$ResponseReceiver 运行信息:读取数据创建缓冲区大小:767