Я получаю записи в цикле while на сокет-сервере. где каждая запись имеет тип сообщения, за которым следуют длина сообщения и фактическое содержание сообщения.
Проблема в том, что, поскольку я получаю около миллиона записей, и каждая запись имеет размер записи 277 байт. Итак, после примерно 40000 записей я получаю ошибку OutOfMemory. Поток кода выглядит примерно так:
while (true) {
msgType = dIn.readByte();
int msgIntType = msgType & 0xff;
// get message length
int msgIntLen = dIn.readInt();
if (msgIntLen != 0) {
msgContent = new byte[msgIntLen];
switch(msgIntType) {
case 4:
//case MSG_DATA:
// MSG_DATA
recordCount++;
processData(msgContent);
if (recordCount == 2000) {
sendACK(dOut, msgIntType);
logger.info("sent ACK for MSG_DATA");
recordCount = 0;
}
break;
}
Я решил проблему OutOfMemory, явно вызвав System.gc () после отправки ACK после обработки каждых 2000 записей, и теперь он отлично работает и способен обрабатывать 1 миллион записей без каких-либо ошибок менее чем за 10 минут. Модифицированный код для оператора case для вызова System.gc () выглядит следующим образом:
case 4:
//case MSG_DATA:
// MSG_DATA
recordCount++;
processData(msgContent);
if (recordCount == 2000) {
sendACK(dOut, msgIntType);
logger.info("sent ACK for MSG_DATA");
recordCount = 0;
System.gc();
}
break;
Но я читал здесь на некоторых других постах, что вызов System.gc () не является хорошим подходом к дизайну? Это так ? Если да, не могли бы вы, ребята, предложить мне другой способ избавиться от этой ошибки OutOfMemory?
Заранее спасибо
-JJ
РЕДАКТИРОВАТЬ: логика для processData ():
public void processData(byte[] msgContent) throws Exception {
InputStreamReader inp = new InputStreamReader(
new ByteArrayInputStream(msgContent));
BufferedReader br = null;
try {
br = new BufferedReader(inp);
String line;
while ((line = br.readLine()) != null) {
process each line
.
}
} catch (Exception e) {
logger.error("exception in " + Utils.getExecutingMethodName(e)
+ " :" + e.getMessage());
} finally {
try {
if (br != null)
br.close();
} catch (IOException e) {
logger.error("Error: " + e);
}
}
}