跟踪文件时,java中的虚拟内存巨大



我使用Apache Tailer从commons IO编写了一个程序,它对一台机器上的许多日志文件执行类似"tail -f"的操作。基本上,它在线程中运行,作为RandomAccessFile打开文件,检查其长度,查找到末尾等。它将收集到的所有日志行发送到客户端。

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

我读了一点关于虚拟内存的知识,明白了它通常是"没什么好担心的"。但是,16gb ?它真的健康吗?

当我用pmap查看进程时,没有显示日志文件名,所以我猜它们不是内存映射。我读到(man pmap) pmap输出的"Mapping"列中的"[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

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

以下几点:

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

  • 虚拟空间大并不一定是坏事。但如果它转化为对物理内存的需求……你没有那么多……


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

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

假设您的应用程序只对日志行进行简单的处理,我建议您将最大堆大小设置为相对较小的大小(例如64Mb)。这样,即使发生泄漏,也不会因为占用大量实际内存而影响到系统的其余部分。

相关内容

  • 没有找到相关文章

最新更新