在我们的SLES12系统上运行此简单的Java程序会保留4GB的虚拟内存:
class Test {
public static void main(String[] args) throws Exception {
Thread.sleep(100000);
}
}
我可以使用以下标志将其减少到1GB:
java -Xmx1m -XX:ReservedCodeCacheSize=5m -XX:CompressedClassSpaceSize=5m -Xss228k -XX:LargePageSizeInBytes=1m -XX:MaxDirectMemorySize=1k Test
仍然,在我们的SLES11系统(具有相同的内存量)上,这仅需要200M。我已经用jconsole检查了所有内存池,没有什么大的问题。两者都与OpenJDK 8.0.202一起运行。知道如何避免这种内存保留吗?
答案 0 :(得分:2)
我使用Windows 10和Java 1.8.0_201。我使用您的参数和 -XX:NativeMemoryTracking = summary 参数运行该应用程序,结果如下:
本机内存跟踪:
总数:保留= 49889KB,已提交= 38613KB
保留的内存代表我们的应用程序可能使用的内存总量。相反,已提交的内存等于我们的应用程序当前正在使用的内存量。 Java 8使用Parallel GC作为默认gc。因此,我添加了 -XX:+ UseSerialGC 参数表来更改默认的GC算法,结果如下:
本机内存跟踪:
总数:保留= 29565KB,已提交= 18349KB
因为类,线程,内部和gc提交区域减少了。您可以在oracle docs.中找到必要的信息 JIT编译器具有线程,这些线程占据了该区域。我使用了 -XX:CICompilerCount = 1 和 -XX:-TieredCompilation 来减少编译器线程的数量。结果是:
本机内存跟踪:
总数:保留= 27481KB,已提交= 16265KB
** *我不建议您执行以下操作。这不是隔离区,可能会意外崩溃。只有我要回答问题。 * **
我使用“ -XX:VMThreadStackSize = 256”参数减少VM线程的堆栈大小。结果是
总数:保留= 25177KB,已提交= 13961KB
结果:使用这些参数,我们将comitted区域从38613KB减少到13961KB,并将保留区域从49889KB减少到25177KB。
注意:我专注于内存预留。我没有考虑应用程序的性能。