我有一台运行 Ubuntu 11.04 (Natty) (64 位) 的新服务器。我首先安装了openjdk
和tomcat6
。当 Tomcat 服务器启动时,它会立即使用480+ MB内存。这似乎太不成比例了,我想知道是否有人有解决方案让 Tomcat 使用200-300 MB(或更少)内存。
我用了记忆功能看到这个:(注意:我删除了所有条目,只留下较大的条目。499MB 的条目是 Tomcat)
user@xyz:~# python memtop-0.9.py
PID | private/writ. mem |command
| current | previous |(truncated)
19776 | 499.3 MB | +++++ |/usr/lib/jvm/java-6-openjdk/bin/java-Djava.util.logging.config.file=/var/lib/tomcat6/conf/logging.properties-Djava.awt.headless=true-Xm
18082 | 148.6 MB | +++++ |/usr/sbin/mysqld
1385 | 3.6 MB | ++ |pythonmemtop-0.9.py
RAM usage: ============================================== 69.3 %
此外,您还可以看到我安装了哪些 JDK 和 Tomcat 包:
user@xyz:~# dpkg --get-selections | grep jdk
default-jdk install
openjdk-6-jdk install
openjdk-6-jre install
openjdk-6-jre-headless install
openjdk-6-jre-lib install
user@xyz:~# dpkg --get-selections | grep tomcat
libtomcat6-java install
tomcat6 install
tomcat6-admin install
tomcat6-common install
tomcat6-user install
Tomcat 的启动脚本设置Xmx
为128米:
JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
有人知道我该怎么做才能将内存消耗降低到更合理的水平吗?我不明白为什么 JVM 和 Tomcat 一起需要消耗这么多内存。
編輯
为了好玩,我下载了Tomcat 6直接运行启动脚本。请记住,没有編輯这次设置了值。运行此命令时,记忆功能显示 Tomcat 正在使用737 MB值得记忆!
这让我相信开放的JDK使用大量 JVM 内存。
我尝试了同样的事情,下载了新的 .zip 文件Tomcat 7-- 同样的问题。它正在使用740 兆的記憶。
我安装了 Sun JRE/JDK。内存消耗下降到大约400 MB(从近 500 MB 下降)。这仍然比我希望的内存使用量要多!
(sun-java6-bin、sun-java6-jdk、sun-java6-jre)
当我运行时top
,我得到了这个:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13749 tomcat6 20 0 481m 68m 9892 S 0 7.4 0:02.85 java
我意识到并预期 64 位机器/JVM 将使用更多内存,但我没想到会这么高。我运行的 VM 只保证有 512MB。
答案1
---- 编辑以提供示例,因为要点没有表达清楚 ----
一个进程启动并请求 1 GB 内存。
然后该进程启动 8 个线程(所有线程都可以访问分配的 1 GB 内存)。
有人运行一个工具来确定使用了多少内存。该工具的工作原理如下:
- 查找每个可调度的项目(每个线程)。
- 查看它可以访问多少内存。
- 把那段记忆加在一起
- 報告數額。
该工具将报告该进程正在使用 9 GB 内存,而(希望)很明显有八个生成的线程(以及原始进程的线程)都使用相同 GB 的内存。
这是某些工具报告内存时的一个缺陷;但是,这不是一个容易修复的缺陷(因为修复它需要更改一些非常老旧(但很重要)的工具的输出)。我不想成为重写 top 或 ps 的人,这会使操作系统不符合 POSIX。
---- 原始帖子如下 ---- 某些版本的内存报告工具(如 top)会错误地将线程(所有线程都可以访问同一内存)与进程混淆。因此,生成五个线程的 tomcat 实例会错误地报告其内存消耗量五倍。
唯一可以确定的方法是分别列出进程及其内存消耗,然后读取其中一个线程(像进程一样列出)的内存。这样,您就知道应用程序的真实内存消耗。如果您依赖为您执行加法的工具,您将高估引用相同共享内存的线程数实际使用的内存量。
我曾经有过配备 2 GB 内存(和 1 GB 交换空间)的机器,报告称之前在一个线程特别繁重的应用程序上使用的内存约为 7GB。
为了更好地理解许多工具如何报告内存,看这里如果他们的 Python 代码正在解析其中一个工具的文本,或者从相同的系统调用获取数据,那么它就会受到过度报告内存的相同错误的影响。