2009-07-08 84 views
59

後讀數已經問的問題關於這個主題和大量的谷歌搜索我仍然不能夠有-Xms選項JVM堆參數

我的問題是一個明確的說法:什麼是java -Xms=512m -Xmx=512mjava -Xms=64m -Xmx=512m之間的區別?

現在我有以下答案:

唯一的區別是,將我的應用程序的運行和內存分配的數量期間運行的垃圾收集的次數。我對嗎 ?

下面是我對這個答案的原因:使用的物理內存真的512M啓動後

-Xms選項設置爲512m不會導致我的申請。我想這與現代操作系統虛擬內存管理和懶惰頁面分配有關。 (我注意到,設置-Xms512M64M不會在所有無論是在Linux頂部或通過在Windows任務管理器中報告的初始使用的內存更改)

有人可以幫助我瞭解這個Xms的影響選項或指向我的鏈接,這將有助於我理解它?

在此先感謝

馬努

回答

31

總結鏈接後發現的信息: JVM分配由-Xms指定的數量,但操作系統通常不會分配實際頁面直到需要它們。因此,JVM按Xms指定的方式分配虛擬內存,但只根據需要分配物理內存。

您可以通過使用Sysinternals的Process Explorer而不是Windows上的任務管理器來查看此信息。

所以使用-Xms64M和-Xms512M之間有一個真正的區別。 但是我認爲最重要的區別是你已經指出的區別:如果你真的需要512MB但是隻能從64MB開始的話,垃圾回收器會更頻繁地運行。

4

如果你寫道: -Xms512m -Xmx512m 當它啓動,java的分配在RAM中爲他的過程和着增加的那些時刻512米。

-Xms64m -Xmx512m 當它啓動時,java只爲他的進程分配64m的ram,但是java可以增加他的內存佔用,而512m。

我認爲第二件事情會更好,因爲你給java自動內存管理。

+0

我知道。但是,「Java那時候分配的512m」究竟意味着什麼?這種內存似乎沒有得到有效分配,因爲我的512M字節系統能夠啓動幾個其他應用程序,而不需要交換和重複我只有幾兆字節被我的Java應用程序使用。 – 2009-07-08 14:43:24

+1

爲什麼這是downvoted?除了最後一句可能正確也可能不正確之外,它在技術上是正確的。在一個高性能的世界中,讓java通過一個單獨的brk()分配所需的所有內存通常會更智能。在其他情況下,在使用內存時分配內存可能會更聰明。 – Fredrik 2009-07-08 14:59:54

+0

我自己並沒有低調回答這個問題。關於你的評論,我有同樣的問題,比我問丹: 是否有任何「風險」或缺點將Xms值設置爲與Xmx相同的值? 謝謝 Manu – 2009-07-08 15:09:03

34

JVM將以初始堆級別的內存用量開始。如果maxheap更高,則隨着內存要求超過當前內存,它將增長到maxheap大小。

所以,

  • -Xms512m -Xmx512m

JVM有512 M開始,從來沒有調整大小。

  • -Xms64m -Xmx512m

JVM始於64M,長(可達512最大上限)如果MEM。要求超過64.

5

JVM自動調整堆大小,這意味着它將嘗試爲您的應用程序找到最佳堆大小。 -Xms和-Xmx只是指定JVM可以操作的範圍並調整堆的大小。如果-Xms和-Xmx的值相同,那麼JVM的堆大小將保持不變。

通常最好只設置-Xmx並讓JVM找到最佳的堆大小,除非有特定的原因需要在JVM啓動時給JVM一大堆。只要JVM實際從操作系統請求內存,我相信它取決於JVM的平臺和實現。我想,它不會要求內存,直到你的應用程序真正需要它。 -Xmx和-Xms只保留內存。

14

除了標準堆參數-Xms-Xmx它也是很好的瞭解-XX:PermSize-XX:MaxPermSize,這是用來指定的燙髮根空間的大小,因爲即使你可能在堆在其他代空間,您可以運行的內存,如果你的perm gen空間變滿了。這個鏈接也有一些important JVM parameters很好的概述。

0

scalamy_file.scala創造了這個玩具的例子:

scala -J-Xms500m -J-Xmx7g my_file.scala 

scala -J-Xms7g -J-Xmx7g my_file.scala 

當然,還有在-Xms500m版本明顯的停頓:

object MyObject { 

    def main(args: Array[String]) { 
     var ab = ArrayBuffer.empty[Int] 

     for (i <- 0 to 100 * 1000 * 1000) { 
      ab += i 
      if (i % 10000 == 0) { 
       println("On : %s".format(i)) 
      } 
     } 
    } 
} 

我跑了。我確信短暫停頓是垃圾收集運行,而長時間停留是堆分配。