2013-02-04 20 views
3

今天注意到了某種有意義的東西,但我無法準確解釋語義。Java內存和Windows

基本上我創建一個普通的老java main方法,並在它有一個永無止境的while循環。在這個循環中,我創建了一些字符串並將它們放在一個HashMap中。我真正想要的是一個運行並在一段時間內建立內存利用率的進程。

public class Test { 

public static void main(String[] args) throws InterruptedException { 
    final HashMap<String, String> names = new HashMap<String, String>(); 
    while(true) { 
     names.put(new Date().toString(), "lskjflksjdflksjdflkjsieurlskjflksn,kdsgkjsdlkfjslkdjfs"); 
     Thread.sleep(50); 
    } 
} 

}

的過程開始-Xms512m -Xmx512m

一旦開始,我可以使用procexp.exe來查看我的java進程。我試圖理解的是虛擬內存和物理內存。虛擬存儲器(專用字節)似乎映射到所請求的jvm大小,即512MB。從過程的概況中,我假設物理內存(工作集)是進程使用的實際內存,隨着時間的推移,隨着我的進程生成更多的字符串值並填充地圖,這些內存正在逐漸增加。它總是比512MB少很多。

所以我的問題是,爲什麼Java使用虛擬內存?

難道這不全是在物理內存嗎?

因爲我使用虛擬內存,這是否意味着它交換到磁盤?

性能不好嗎?

有沒有辦法強制它在RAM中以獲得更好的性能?

在Windows上這種事情的任何好的文章將是偉大的。

+0

我建議用VisualVM來觀察這個過程。 GC將確保每個頁面都被觸摸,從而將其強制存入內存。 –

回答

2

爲什麼Java中使用虛擬內存?

所有用戶應用程序都使用虛擬內存與操作系統內存交互。由操作系統將其映射回物理RAM /磁盤(通過頁表)。因爲您使用-Xms512m啓動了JVM,所以啓動時它將請求500 MB的虛擬內存空間,但操作系統選擇不爲此預留500 MB的物理RAM,因爲它可能永遠不會使用。

是不是全部都在RAM中,即物理內存?

除非你的機器使用了很高的百分比(> 75%左右),它的所有物理內存和基於JVM的應用程序最近都訪問了它的一些數據,否則JVM將全部放在RAM中。

因爲我使用虛擬內存,這是否意味着它交換到磁盤?

否參見上文。

這對性能有壞處嗎?

分頁可能會導致數據分頁到磁盤的應用程序的性能不佳。 Windows會盡量減少在幾個方面,這影響:

  1. 虛擬內存頁面發送到磁盤是最近最少使用的那些
  2. 有被設計爲從拉頁退了優化磁盤如果Windows能夠檢測到它即將被使用(即,如果您開始迭代通過地圖中的鍵,則Windows將嘗試在迭代達到之前將包含下一個鍵塊的頁面撤回)

另外,正如我所提到的,您很可能不會分頁到磁盤。

有沒有辦法強制它在RAM中以獲得更好的性能?

您可以關閉窗口中的頁面文件。 Here's a Youtube video with instructions.

在Windows上這種事情的任何好的文章將是偉大的。

+0

JVM可能在RAM中,但對象可能不是..有些可能放在虛擬內存文件 –

+0

謝謝@Ryan。你提到分頁是不好的。我還通過procexp.exe看到頁面錯誤,因爲這裏有一個+ ve Delta,這是否意味着我是分頁? – imrichardcole

+0

有時,即使您僅使用較小比例的物理RAM,Windows也會開始分頁最近未使用的數據。如果您在任務管理器中看到頁面錯誤,那麼Windows會分頁您的應用程序。 –

0

對於32位計算機上的每個進程,可尋址內存爲4GB,計算機實際是否具有4GB實際RAM內存並不重要。

例如,如果您的計算機具有2GB的RAM,則對於JVM,它看起來像有4GB的內存。另外2GB內存來自將內存映射到HDD中的文件(這是虛擬內存)。

如果有多個進程在運行,對每個進程來說,它似乎是計算機上運行的唯一進程,並且具有4GB的可尋址內存。由於JVM不會是唯一的進程運行,操作系統中的內存管理器可能會決定將未使用內存的內容推送到虛擬內存文件中。這取決於操作系統的決定。

既然是交換到磁盤,在性能上的滯後會noticable(除非它是一個固態硬盤)