例如,我将JVM的最大堆设置为4GB。但是,一旦我的应用程序达到3GB,操作系统就开始将一些内存交换到磁盘上。此时,有几个对象已经超出了作用域,JVM可以首先垃圾收集旧对象,而不是请求更多内存。就性能而言,运行垃圾回收比进行内存交换要好得多。对于这种情况,JVM垃圾收集是明智的,还是完全不知道呢?我们能以某种方式调优JVM以解决这种情况吗?
我知道垃圾收集有可能在达到3GB之前运行,因此我们根本不需要交换内存,但这并没有真正回答我的问题。
编辑:允许假设我的机器有超过4GB的内存,但有时还有其他应用程序占用一些内存,而我的内存不足4GB。考虑到大多数情况下我将拥有4GB,我宁愿不必减少最大堆大小,但我想知道在其他情况下GC是否足够聪明。
发布于 2010-08-23 13:35:36
JVM很幸运地不知道底层操作系统内存管理。我记得不久前我参加了一次关于GC优化的JavaOne会议,发言者强调,您应该始终确保有足够的空闲内存(RAM,而不是交换内存)供JVM运行,以避免不惜一切代价分页,所以永远不要为JVM分配比系统中给定时间可用的内存更多的内存。更重要的是,由于某些GC收集算法的工作方式,如果它们正在收集的内存块被分页,可能会造成巨大的性能损失。
因此,千万不要给JVM提供比系统中物理可用的内存更多的内存,或者如果您期望内存消耗随着时间的推移会因为某些外部进程而增加,那么就分配一个堆空间,以确保它永远不会被分页。如果您不能满足这些条件,那么您需要更多的RAM :)
更新:做了一些搜索,所以我找到了这。在这里,kdgregory认为,分页不应该是一个问题,因为GC的工作方式,但他考虑分页是由于正常情况,即内存暂时不被触摸,这不是您的情况,因为您将耗尽内存,您肯定会开始分页。另外,如果您正在运行一些Linux版本,请查看John的答案和他的伟大的博客文章,解释如何理解和调优Linux中的交换。
发布于 2010-08-23 11:36:19
GC不知道这种情况。您不应该指定比机器上可用的内存量更大的堆。解决方案是减少堆大小,并确保没有其他程序占用所有内存。
实际上,即使在C中,也不认为有一种简单的方法来检查进程是否正在交换(如果存在,请添加注释)。
https://stackoverflow.com/questions/3547072
复制相似问题