java內存學習

[b]概念[/b]
垃圾收集的目的在於清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。而其中,[color=red]內存溢出[/color]就是你要求分配的java虛擬機內存超出了系統能給你的,系統不能滿足需求,於是產生溢出。
[color=red]內存泄漏[/color]是指你向系統申請分配內存進行使用(new),可是使用完了以後卻不歸還(delete),結果你申請到的那塊內存你自己也不能再訪問,該塊已分配出來的內存也無法再使用,隨着服務器內存的不斷消耗,而無法使用的內存越來越多,系統也不能再次將它分配給需要的程序,產生泄露。一直下去,程序也逐漸無內存使用,就會溢出。

[b]空間劃分[/b]
在Java虛擬機規範中,提及瞭如下幾種類型的內存空間:
棧內存(Stack):每個線程私有的。
堆內存(Heap):所有線程公用的。
方法區(Method Area):存放了每個加載類的反射信息、類函數的代碼、編譯時常量等信息。
原生方法棧(Native Method Stack):主要用於JNI中的原生代碼,平時很少涉及。

而Java的使用的是堆內存,java堆是一個運行時數據區,類的實例(對象)從中分配空間。Java虛擬機(JVM)的堆中儲存着正在運行的應用程序所建立的所有對象,“垃圾回收”也是主要是和堆內存(Heap)有關。
垃圾回收的概念就是JAVA虛擬機(JVM)回收那些不再被引用的對象內存的過程。一般我們認爲正在被引用的對象狀態爲“alive”,而沒有被應用或者取不到引用屬性的對象狀態爲“dead”。垃圾回收是一個釋放處於”dead”狀態的對象的內存的過程。而垃圾回收的規則和算法被動態的作用於應用運行當中,自動回收。

Sun JVM 1.3 有兩種最基本的內存收集方式:一種稱爲copying或scavenge,將所有仍然生存的對象搬到另外一塊內存後,整塊內存就可回收。這種方法有效率,但需要有一定的空閒內存,拷貝也有開銷。這種方法用於minor collection。另外一種稱爲mark-compact,將活着的對象標記出來,然後搬遷到一起連成大塊的內存,其他內存就可以回收了。這種方法不需要佔用額外的空間,但速度相對慢一些。這種方法用於major collection.

[b]時間劃分[/b]
一些對象被創建出來只是擁有短暫的生命週期,比如 iterators 和本地變量。另外一些對象被創建是擁有很長的生命週期,比如 高持久化對象等。
垃圾回收器的分代策略是把內存區劃分爲幾個代,然後爲每個代分配一到多個內存區塊。當其中一個代用完了分配給他的內存後,JVM會在分配的內存區內執行一個局部的GC(也可以叫minor collection)操作,爲了回收處於“dead”狀態的對象所佔用的內存。局部GC通常要不Full GC要快很多。

JVM定義了兩個代,年輕代(yong generation)(有時稱爲“nursery”託兒所)和老年代(old generation)。年輕代包括 “Eden space(伊甸園)”和兩個“survivor spaces”。虛擬內存初始化的時候會把所有對象都分配到 Eden space,並且大部分對象也會在該區域被釋放。 當進行 minor GC的時候,VM會把剩下的沒有釋放的對象從Eden space移動到其中一個survivor spaces當中。此外,VM也會把那些長期存活在survivor spaces 裏的對象移動到 老生代的“tenured” space中。當 tenured generation 被填滿後,就會產生Full GC,Full GC會相對比較慢因爲回收的內容包括了所有的 live狀態的對象。pemanet generation這個代包括了所有java虛擬機自身使用的相對比較穩定的數據對象,比如類和對象方法等。
[img]http://dl.iteye.com/upload/attachment/539446/1d1077cc-2549-349b-bbc6-8facd4b2d058.jpg[/img]
最後,總結一下各區內存:
Eden Space (heap): 內存最初從這個線程池分配給大部分對象。
Survivor Space (heap):用於保存在eden space內存池中經過垃圾回收後沒有被回收的對象。
Tenured Generation (heap):用於保持已經在 survivor space內存池中存在了一段時間的對象。
Permanent Generation (non-heap): 保存虛擬機自己的靜態(refective)數據,例如類(class)和方法(method)對象。Java虛擬機共享這些類數據。這個區域被分割爲只讀的和只寫的,
Code Cache (non-heap):HotSpot Java虛擬機包括一個用於編譯和保存本地代碼(native code)的內存,叫做“代碼緩存區”(code cache)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章