我正在为我的 Java Web 应用程序进行内存管理分析,
在启动我的 tomcat 之前,可用内存约为 595 MB,一旦我启动服务器,可用内存就变为 151 MB。当我进行堆转储时,对象占用了 262 MB。
那么 tomcat 单独会占用剩下的 181 MB 吗?
另一个问题是,我运行了 500 个用户的负载测试。可用内存变为 8MB,当我在此处进行堆转储时,它大约为 265MB。因此,可用空间 151 MB 减少到 8MB,可能是什么原因
答案1
首先,阅读并理解http://www.linuxatemyram.com/为什么“可用”内存数量比您想象的要低得多。
其次,Java 会从操作系统预先分配整个堆,尽管它不会触碰或弄脏这些页面,直到它们被实际使用。这为您提供了如下顶级输出:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
9521 pjc 17 0 1288m 524m 25m S 0.0 13.3 58:31.92 java
这是我运行 Eclipse 时的情况;VIRT 列显示 Java 的最大堆大小可能为 1024Mb;除此之外还有用于存储已编译 Java 的库和内存。但是目前只有 524Mb 在 RAM 中。
您的堆转储是您的应用程序使用了多少内存的最佳指南 - 前提是它在完成垃圾收集之后。
答案2
操作系统很聪明,并不愚蠢。它知道空闲内存是浪费的内存,并不比系统中根本没有的内存好。如果你的 4GB 机器今天只使用了 3GB,明天你就可以使用 5GB。
因此,它会将可能用到的内容保存在 RAM 中。如果以后可以使用,那么性能就会提高。令人惊讶的是,如果以后不能使用,那么仍然性能上的优势在于,如果将其释放,则只需再次使用它即可。(这需要两次操作,而将其从一种用途直接切换到另一种用途只需一次操作。)
现代操作系统只有在别无选择的情况下才会释放少量内存。
答案3
使用psi 探针真正了解 JVM 中发生的事情。或者 VisualVM,但 psi-probe 更易于访问。