[英]Memory size feasible via Virtual Memory vs RAM
我正在嘗試實例化一個巨大的ArrayList
List<Integer> list = new ArrayList<Integer>(Integer.MAX_VALUE);
在 eclipse 中運行它,我得到:
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
如果我做:
List<Integer> list = new ArrayList<Integer>(Integer.MAX_VALUE - 2);
我得到一個不同的錯誤:
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory failed; error='The paging file is too small for this operation to complete'
#
# there is insifficent memory for the Java Runtime Environment to continue.
我在 eclipse 的運行配置中使用以下設置啟動程序:
-Xmx8G
那么這里的問題是什么? 即使我增加到-Xmx16G
它仍然給出相同的錯誤
更新
我有點困惑,RAM的實際大小在這里重要嗎? 由於分頁,進程不能訪問無限的虛擬 memory 嗎?
我有點困惑,RAM的實際大小在這里重要嗎?
是的,它確實。
由於分頁,進程不能訪問無限的虛擬 memory 嗎?
是的,他們確實...以您需要磁盤空間來保存虛擬 memory 頁面為模。 確實,“那*就是您收到此錯誤的原因:
The paging file is too small for this operation to complete.
這個“修復”是使頁面文件更大。 這必須在操作系統級別完成。
但是,分頁意味着操作系統必須在需要時將頁面從磁盤復制到 memory。 為了給它們騰出空間,它必須將其他(臟)頁面從 RAM 復制到磁盤。 所有這些復制都使用 CPU 和磁盤 I/O 帶寬並減慢您的程序。
一個典型的 (C/C++) 程序通常可以在一定程度上解決這個問題,具體取決於應用程序的 memory 訪問模式。 但是在 Java 中你會遇到 GC 偶爾運行的問題。 在一段時間內,GC 將以(基本上)隨機順序訪問大量頁面中的對象。 對於“完整”的垃圾收集來說,情況更糟。
如果應用程序正在訪問的頁面集(即“工作集”)的大小大於可用 RAM 頁面的數量,則您可能會“崩潰”; 即通過頁面的讀取和寫入使 I/O 系統飽和。 這對性能來說真的很糟糕。 在極端情況下,它會使操作系統無響應。
因此,使用大於可用物理 RAM 的堆運行 Java 應用程序是一件有潛在危險的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.