2

我使用 commons IO 中的 Apache Tailer 在机器上的许多日志文件上制作了一个类似于“tail -f”的程序。基本上它在一个线程中运行,将文件作为 RandomAccessFile 打开,检查它的长度,寻找到最后等。它将收集到的所有日志行发送到客户端。

有点不舒服的是,在 Linux 上它可以显示大量的 VIRT 内存。现在它说 16.1g VIRT (!!) 和 203m RES。

我已经阅读了一些关于虚拟内存的内容,并了解到它通常“没什么好担心的”。但是仍然是 16 GB?真的很健康吗?

当我用 pmap 查看进程时,没有显示任何日志文件名,所以我猜它们不是内存映射的。我读到(man pmap)pmap 输出的“映射”列中的“[anon]”意味着“分配的内存”。这是什么意思?:)

但是, 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

..所以,嗯..我猜它在大型机器上占据了更多堆,因为最大限制(方式)更高?而且我还认为始终明确指定这些值是个好主意。

4

1 回答 1

1

有几件事:

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

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


嗯,我实际上是在没有任何 JVM 参数的情况下运行它的。是好还是坏?:-)

我现在知道了。是的,这很糟糕。JVM 在大型 64 位机器上的默认堆大小远远超出您的实际需要。

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

于 2013-03-14T16:47:00.163 回答