1.先了解幾個概念:
-
①.java數據類型氛圍基礎數據類型(:boolean、byte)和引用數據類型(類、接口、數組)
-
②.堆、方法區 、棧
堆區:
提供所有類實例和數組對象存儲區域
jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身
棧區:
每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中
每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。
方法區:
又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。
方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。
運行時常量池都分配在 Java 虛擬機的方法區之中 例子
這個例子中
public void test(){
A a = new A();
int b = 1;
}
public class A{
}
a是A對象的引用所以放在棧中,A是自定義對象所以放在堆中.
b是基礎數據類型所以在棧中.
小結
這裏用一個在別處看到的栗子總結再好不過
堆和棧的區別可以用如下的比喻來看出:
使用棧就象我們去飯館裏吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就
走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自
由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由
度大。
2.jvm heap區域是分代的,分爲年輕代,老年代和持久代
年輕代:所有新生成的對象首先都是放在年輕代的。年輕代的目標就是儘可能快速的收集掉那些生命週期短的對象。
年老代:在年輕代中經歷了N次垃圾回收後仍然存活的對象,就會被放到年老代中。因此,
可以認爲年老代中存放的都是一些生命週期較長的對象。
持久代:用於存放靜態文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,
但是有些應用可能動態生成或者調用一些class,例如Hibernate 等
3.Full Gc
gc的主要作用是回收堆中的對象。
Full GC 是清理整個堆空間—包括年輕代和永久代。
4.垃圾回收算法
猿們都知道JVM的內存結構包括五大區域:程序計數器、虛擬機棧、本地方法棧、堆區、方法區。
其中程序計數器、虛擬機棧、本地方法棧3個區域隨線程而生、隨線程而滅,因此這幾個區域的內
存分配和回收都具備確定性,就不需要過多考慮回收的問題,因爲方法結束或者線程結束時,
內存自然就跟隨着回收了。而Java堆區和方法區則不一樣、不一樣!(怎麼不一樣說的朗朗上口),
這部分內存的分配和回收是動態的,正是垃圾收集器所需關注的部分。
引用計數算法:
優點:實現簡單,效率較高,在大部分情況下是一個不錯的算法。
缺點:引用計數法很難解決對象之間相互循環引用的問題,主流Java虛擬機沒有選用引用計數法來管理內存。
標記-清除
優點:標記-清除算法不需要進行對象的移動,只需對不存活的對象進行處理
缺點:產生內存不連續使用,碎片問題
複製算法
優點:解決內存不連續,碎片問題
缺點:內存使用增加一倍,資源浪費
標記-整理(Mark-Compat)算法
優點:標記-整理算法是在標記-清除算法的基礎上,又進行了對象的移動,使得內存對象連續使用
缺點:移動內存對象消耗資源,對象整理代價較高
分代收集(Generational Collection)算法(年輕態,老年態)