1、java內存管理分為內存分配和內存回收,都不需要程序員負責。
2、垃圾回收的機制主要是看對象是否有引用指向該對象。
java對象的引用包括
強引用
軟引用
弱引用
虛引用
3、強引用
是指創建一個對象並把這個對象賦給一個引用變量。
強引用有引用變量指向時永遠不會被垃圾回收。即使內存不足的時候。
4、軟引用
軟引用通過SoftReference類來實現
軟引用的對象當系統內存充足時和強引用沒有太多區別,但內存不足時會回收軟引用的對象。
很多對象,但是只有一個引用指向他們(可分別指定)
public static void main(String[] args){
//創建軟引用數組
SoftReference<Person> [] p = new SoftReference[100]; //100000
//賦值
for(int i = 0; i< p.length ;i++){
p[i] = new SoftReference<Person>(new Person("name"+i ,i));
}
//測試
System.out.println(p[1].get());
System.out.println(p[4].get());
//通知系統進行回收
System.gc();
System.runFinalization();
System.out.println("---------------");
System.out.println(p[1].get());
System.out.println(p[4].get());
}
當系統內存充足時,系統不會進行軟引用的內存回收,
當系統不足時將會回收軟引用的對象。
當用 java -Xmx1m -Xms1m SoftReferenceTest 命令時強制堆內存為1m時 軟引用引用對象
將被回收。(可以創建10000個對象)
5、weakReference
弱引用通過weakReference類來實現
public static void main(String[] args) {
String str = new String("JAVA講義");
// String str = "JAVA講義"; 這種創建是在常量池中
//創建一個如引用對象 指向 str對象
WeakReference<String> wr = new WeakReference<String> (str);
str =null;
//輸出
System.out.println(wr.get());//JAVA講義
//強制垃圾回收
System.gc();
System.out.println(wr.get());//null
}
弱引用具有很強的不確定性。因為垃圾回收每次都會回收弱引用的對象。
6、虛引用
軟引用和弱引用可以單獨使用,虛引用不能單獨使用,虛引用的作用是就跟蹤對象被垃圾回收的
狀態,程序可以通過檢測與虛引用關聯的虛引用隊列是否已經包含了指定的虛引用,從而了解
虛引用的對象是否即將被回收。
PhantomReference對象實現
虛引用通過PhantomRefence類實現,它本身對對象沒有影響,類似與沒有應用,對象甚至感覺不到
虛引用的存在,如果一個對象只有一個虛引用存在,那么他就類似沒有應用存在。
public static void main(String[] args){
// 創建一個對象
String str = new String("JAVA講義");
// 創建一個引用隊列
ReferenceQueue<String> rq = new ReferenceQueue<String>();
//創建一個虛引用,指定引用對象.不能單獨使用必須關聯引用隊列
PhantomReference pr = new PhantomReference(str,rq);
//切斷強引用
str =null;
//試圖取得虛引用對象
System.out.println(pr.get());
//垃圾回收
System.gc();
System.runFinalization();
//取出引隊列中的最先進入隊列的引用與pr進行比較
System.out.println(rq.poll()==pr);
}
//null
//true
當程序強制垃圾回收后,只有虛引用引用字符串對象將會被垃圾回收,當被引用的對象被回收后,
對應的引用將被添加到關聯的引用隊列中。
7、如果使用軟引用,弱引用,虛引用的引用方式引用對象,垃圾回收就能夠隨意的釋放這些對象,
若果希望盡可能減小程序在起聲明周期中所占用的內存大小,可以靈活使用這些引用。
如果使用了這些引用就不能保留這些對象的強引用(強制引用應該置null),否則就浪費了這些類提供的任何好處。