java - 删除分配给字节数组的内存

标签 java sockets out-of-memory heap-memory

我正在套接字服务器上的 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;

}

我通过在每处理 2000 条记录后发送 ACK 后显式调用 System.gc() 解决了 OutOfMemory 问题,现在它工作得很好,能够在 10 分钟内处理 100 万条记录,没有任何错误。用于调用 System.gc() 的 case 语句的修改代码如下所示:

            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);
        }
    }
}

最佳答案

您是否未能关闭某些资源并依赖终结器线程来获取它们?或者您是否刚刚添加了一个终结器(可能不必要),该终结器会阻止立即释放大量内存。

关于java - 删除分配给字节数组的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5807465/

相关文章:

java - 如何检查我的程序是否有 Java 更新

java 能否在一个构造器( constructor )中调用另一个构造器

android - 如何避免Android中Fragments的内存溢出问题?

java - 使用 StringBuilder 覆盖普通 POJO 的 toString() 时避免内存效率低下

Java String - 如何制作将字符串添加到字符串中的函数?

excel - 如何使用 ftp、http 或套接字从电子表格中使用 VBA for Microsoft Office 上传数据?

c - Linux, C, epoll(), read() 数据不完整?

java - 在Java中获取传入输入流的IP

Android Outofmemory错误,外部存储器

Java String.format args索引不一致