2

我有一个简单的应用程序,可以将数据从一台机器传输到另一台机器。随着应用程序的运行,堆的大小正在缓慢增加。于是我dump了堆,分析了一下,发现zmq.poll.Poller消耗的内存最大。它们属于线程' iothread-2':

堆截图在这里

在此处输入链接描述

我的应用程序演示是这样的:

public static void main(String[] args) throws Exception {
    ZMQ.Context context = ZMQ.context(1);
    ZMQ.Socket socket = context.socket(ZMQ.DEALER);
    socket.connect("tcp://localhost:5550");
    ZMQ.Poller poller = context.poller(1);
    poller.register(socket, ZMQ.Poller.POLLIN);

    while(!Thread.currentThread().isInterrupted()) {
        poller.poll(5000);
        if (poller.pollin(0)) {
            socket.send("message"); // send message to another machine
            String msg = socket.recvStr(); // get the reply

            // do some stuff
            Thread.sleep(1000);
        }
    }
}

当我检查Poller堆中的对象时,我发现有 400 万个HashMap$Node,并且 hashmap 节点的值是一个包含 10 个空对象数组列表的列表。

堆被命令转储:
jmap -dump:live,format=b,file=dump.hprof [pid]

jdk 是 1.8.0_131,操作系统是 CentOS 7.2.1511 和 jeromq 0.4.2

我用poller错了吗?非常感谢任何帮助的人!

4

1 回答 1

2

这个问题似乎与缺少资源管理有关:

本机 API 文档对此非常严格:

zmq_msg_close()函数应通知 ØMQ 基础设施,与所引用的消息对象相关联的任何资源msg都不再需要并且可以被释放。与消息对象相关的资源的实际释放应由ØMQ推迟,直到消息或底层数据缓冲区的所有用户都表明不再需要它。

应用程序应确保在zmq_msg_close()不再需要消息时调用它,否则可能会发生内存泄漏。请注意,成功后不需要这样做zmq_msg_send()

尝试包含适当的显式消息处理并且应该会看到改进(但是,取决于 jeromq 版本、垃圾收集动态等)。

于 2018-03-26T19:55:38.453 回答