我使用来自commons IO的Apache Tailer在一台机器上的许多日志文件上创建了一个类似“tail -f”的程序。基本上它在一个线程中运行,将文件作为RandomAccessFile打开,检查其长度,寻找结束等。它将收集的所有日志行发送给客户端。
有点不舒服的是,在Linux上它可以显示大量的VIRT内存。现在它说16.1g VIRT(!!)和203m RES。
我已经阅读了一些有关虚拟内存的内容,并了解到它通常“无需担心”..但仍然是16 GB?它真的很健康吗?
当我用pmap查看进程时,没有显示任何日志文件名,所以我猜它们不是内存映射的。我在(映射)列的“映射”列中读到(man pmap)“[anon]” pmap输出表示“已分配的内存”。这是什么意思? :)
但是,pmap -x显示:
Address Kbytes RSS Dirty Mode Mapping
...
---------------- ------ ------ ------
total kB 16928328 208824 197096
..所以我认为它毕竟不是驻留在RAM中。但是当打开这样的文件,寻找它的结尾等时,它如何以内存方式工作?
我应该担心所有那些GB的VIRT内存吗?它现在“监视”84个不同的日志文件,磁盘上的这些文件的总大小为31414239字节。
修改 我只是在另一个不那么“类似生产”的Linux机器上进行了测试,并没有获得相同的数字。 VIRT最多只有2.5 GB。我发现一些默认的JVM设置不同(用“java -XX:+ PrintFlagsFinal -version”检查):
Value Small machine Big machine
InitialHeapSize 62690688 2114573120
MaxHeapSize 1004535808 32038191104
ParallelGCThreads 2 13
..所以,嗯..我猜它在大机上抓了更多的堆,因为最大限制是(路)更高?而且我也猜测总是明确指定这些值是个好主意。
答案 0 :(得分:1)
有几件事:
每个Tailer实例都有自己的线程。每个线程都有一个堆栈。默认情况下(在64位JVM上),每个线程堆栈都是1Mb,因此您将使用84Mb进行堆栈。您可以考虑在启动时使用-Xss选项减少它。
一个大的virt大小不一定是坏的。但如果它转化为对物理记忆的需求......而你没有那么多......那真的很糟糕。
嗯,我现在实际上没有任何JVM args运行它。是好还是坏? :-)
我现在明白了。是的,这很糟糕。 JVM在大型64位计算机上的默认堆大小远远超过您的实际需要。
假设您的应用程序只对日志行进行简单处理,我建议您将最大堆大小设置为相对较小的大小(例如64Mb)。这样一来,如果你确实遇到泄漏,它就不会通过吞噬大量的实际内存来影响系统的其他部分。