天天看點

Java虛拟機支援的最大記憶體限制

最近在開發的程式。本來我是一直很喜歡的記憶體管理的,不需要擔心配置設定記憶體,隻管配置設定,垃圾收集器自己會給你回收記憶體的。現在開發的程式資料量很大,為了速度快,我準備把所有的資訊加載進記憶體,這樣可以保證快速響應。我還在反複算記憶體,想想自己的資料量,現在剛開始的時候應該夠了(我的機器是4g記憶體,雖然就認3.5g,但是比起我現在的資料量應該沒問題)。

  沒想到第一個實驗的程式,跑了幾個小時,就遇到了out of memory exception了。看看自己的虛拟機設定,我設定的是-xms512m

-xmx1024m。想都沒想,直接改成-xms512m -xmx2048m,結果直接就could not reserve enough space for

object heap。程式都起不來了。這才發現原來最大記憶體還有限制。上網搜了一下,發現很多讨論這個問題的文章。最終在bea的dev2dev論壇發現了最有用的

一篇

  這裡的版主yulimin 做了,得出結論:

  公司

jvm版本                 

最大記憶體(兆)client    最大記憶體(兆)server

  sun

1.5.x                         

1492                           

1520

1.5.5(linux)            

2634                           

2660

1.4.2                         

1564                           

1564

1.4.2(linux)            

1900                           

1260

  ibm

2047                            

n/a

  bea jrockit 1.5 (u3)     

1909                            

1902

  我現在用的是jdk1.6. 0_05,了一下。在client狀态下最大是,我的jdk不認-server參數,測試不了server狀态。估計差不多。

1.6.0                         

1442                          

  看樣子用java想用大記憶體也是不可能的了。而且一般的說法是記憶體太大了,垃圾收集的時間就會長。這也可以了解,一般是記憶體不夠用了才收集的,掃描2g記憶體比1g當然要慢多了,而且記憶體對象多了,估計關系是指數上升的。

  下面附上yulimin的測試方法和測試記錄。

  測試方法:在指令行下用 java -xmxxxxxm -version

指令來進行測試,然後逐漸的增大xxxx的值,如果執行正常就表示指定的記憶體大小可用,否則會列印錯誤資訊。

堆(heap)和非堆(non-heap)記憶體

按照官方的說法:“java

虛拟機具有一個堆,堆是運作時資料區域,所有類執行個體和數組的記憶體均從此處配置設定。堆是在 java

虛拟機啟動時建立的。”“在jvm中堆之外的記憶體稱為非堆記憶體(non-heap

memory)”。可以看出jvm主要管理兩種類型的記憶體:堆和非堆。簡單來說堆就是java代碼可及的記憶體,是留給開發人員使用的;非堆就是jvm留給

自己用的,是以方法區、jvm内部處理或優化所需的記憶體(如jit編譯後的代碼緩存)、每個類結構(如運作時常數池、字段和方法資料)以及方法和構造方法

的代碼都在非堆記憶體中。

堆記憶體配置設定

jvm初始配置設定的記憶體由-xms指定,預設是實體記憶體的1/64;jvm最大配置設定的記憶體由

-xmx指定,預設是實體記憶體的1/4。預設空餘堆記憶體小于40%時,jvm就會增大堆直到-xmx的最大限制;空餘堆記憶體大于70%時,jvm會減少堆

直到-xms的最小限制。是以伺服器一般設定-xms、-xmx相等以避免在每次gc 後調整堆的大小。

非堆記憶體配置設定

jvm使用-xx:permsize設定非堆記憶體初始值,預設是實體記憶體的1/64;由xx:maxpermsize設定最大非堆記憶體的大小,預設是實體記憶體的1/4。

jvm記憶體限制(最大值)

首先jvm記憶體限制于實際的最大實體記憶體(廢話!呵呵),假設實體記憶體無限

大的話,jvm記憶體的最大值跟作業系統有很大的關系。簡單的說就32位處理器雖然可控記憶體空間有4gb,但是具體的作業系統會給一個限制,這個限制一般是

2gb-3gb(一般來說windows系統下為1.5g-2g,linux系統下為2g-3g),而64bit以上的處理器就不會有限制了。

是以說設定vm參數導緻程式無法啟動主要有以下幾種原因:

1) 參數中-xms的值大于-xmx,或者-xx:permsize的值大于-xx:maxpermsize; 2) -xmx的值和-xx:maxpermsize的總和超過了jvm記憶體的最大限制,比如目前作業系統最大記憶體限制,或者實際的實體記憶體等等。說到實際實體 記憶體這裡需要說明一點的是,如果你的記憶體是1024mb,但實際系統中用到的并不可能是1024mb,因為有一部分被硬體占用了。
Java虛拟機支援的最大記憶體限制