虽然问题非常基础,但我愿意理解JVM如何对应用程序进行最大内存分配。我有一个在Windows 2008服务器上运行的应用程序,它承载大约60个虚拟托管服务器[即60个JVM]。每个受管服务器的最大堆数设置为1024m。 Windows配置了32 GB RAM。
现在的问题是,如何最大限度地为JVM分配内存?它是一次完成还是逐步增长?如果一气呵成,Windows如何处理在32 GB RAM包装系统中托管我的应用程序的所有60个托管服务器?
非常感谢任何观点。谢谢。
答案 0 :(得分:3)
JVM实际上会在启动时分配-Xmx
请求的所有内存,以及用于保存JVM可执行文件和内部工作区的额外内存。当您创建线程时,它还会为用于这些线程的堆栈分配内存。
这是因为(1)JVM实际上不使用这个内存,(2)OS提供了一个分页文件。当JVM请求分配时,它会由OS创建承诺,但实际上并不使用所有请求的RAM。由于它实际使用RAM,操作系统将页面与页面文件交换。如果所有进程都在积极使用其RAM,则操作系统必须不断地交换页面;这被称为“捶打”。
-Xms
参数指定初始堆大小在整个堆大小中。 JVM将尝试将内存保留在这些边界内,但如果无法回收足够的垃圾,则允许扩展边界。但是,这些堆增加不会逐步从OS请求更多内存。如果他们这样做,堆将被分段并且大型数组分配可能会失败(因为它不适合连续的内存)。
答案 1 :(得分:1)
JVM最初分配通过-Xms
选项指定的内存量(据我所知默认为32M)。当它耗尽此内存时,它将开始逐步分配新内存,直到达到通过-Xmx
选项指定的数量(默认为64M)。
发生这种情况时,会抛出OutOfMemory
错误。
P.S。当然,这是一个非常简化的算法。事实上,JVM使用了更为复杂的一个。
答案 2 :(得分:1)
如果您希望在启动进程时分配它,则需要提供-Xms,如果只提供-Xmx,则VM将增长到该值,但只有在需要更多内存时才会增加。
答案 3 :(得分:1)
-Xmx参数指定JVM可以使用的最大内存,但不会在启动后立即从操作系统中分配它。它通常在很多步骤中执行增量,因为它需要这样做(即.JVM中的Java应用程序在运行时需要更多内存)。
当然这是默认行为,可以使用许多其他JVM参数进行更改。