我使用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)。这样,即使发生泄漏,也不会因为占用大量实际内存而影响到系统的其余部分。