拖尾文件时java中的巨大虚拟内存

时间:2013-03-14 15:52:04

标签: java memory io apache-tailer

我使用来自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

..所以,嗯..我猜它在大机上抓了更多的堆,因为最大限制是(路)更高?而且我也猜测总是明确指定这些值是个好主意。

1 个答案:

答案 0 :(得分:1)

有几件事:

  • 每个Tailer实例都有自己的线程。每个线程都有一个堆栈。默认情况下(在64位JVM上),每个线程堆栈都是1Mb,因此您将使用84Mb进行堆栈。您可以考虑在启动时使用-Xss选项减少它。

  • 一个大的virt大小不一定是坏的。但如果它转化为对物理记忆的需求......而你没有那么多......那真的很糟糕。


  

嗯,我现在实际上没有任何JVM args运行它。是好还是坏? :-)

我现在明白了。是的,这很糟糕。 JVM在大型64位计算机上的默认堆大小远远超过您的实际需要。

假设您的应用程序只对日志行进行简单处理,我建议您将最大堆大小设置为相对较小的大小(例如64Mb)。这样一来,如果你确实遇到泄漏,它就不会通过吞噬大量的实际内存来影响系统的其他部分。