記憶體回收機制和資料結構棧鏈表,記憶體回收資料結構
1、記憶體回收機制:
(1)沒有引用變數指向的對象,就是垃圾。
舉例:
Test t = new Test();
t=null;
那麼之前建立的對象就是垃圾。
(2)對象沒有被使用是另外一種垃圾。
new Test();
new Test().toString();
區別在於第一個對象很明顯沒有指向,是垃圾。但是第二個不是,因為他被使用了。
2、回收時機。
通常情況下,要在滿了的時候回收。
其次在調用
System.gc();//通常情況下會立刻回收。等效於Runtime.getRuntime.gc();
3、finalize() 方法,是任何對象都有的一個方法。(Object )
任何對象在被回收之前都會調用的一個方法。finalize().
這個方法的函數體是空的。
方法描述:
Runs the garbage collector.Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.
The call System.gc() is effectively equivalent to the call:
Runtime.getRuntime().gc()
運行記憶體回收行程:
調用gc方法 建議java虛擬機器增強效能通過回收未利用的對象,讓記憶體中已經被佔用的快速能夠再次被使用。當控制器返回這個方法調用後,java虛擬機器能夠更好地重新聲明控制項,從所有廢棄的對象那裡。
調用System.gc()方法等效於 Runtime.getRuntime.gc();
記得找到 class 來執行
Code:package GarbageCollectin;public class GarbageCollection { public static void main(String[] args) { GarbageCollection gc = new GarbageCollection(); new GarbageCollection(); new GarbageCollection().toString(); gc = null; Runtime.getRuntime().gc();//等效於 System.gc(); System.runFinalization(); //這樣直接運行並沒有結果。 }}
資料回收前對記憶體的數量被佔用的數量是:3932k
回收後是: 728K
後面的 251392K是虛擬機器佔用的總的記憶體大小。
在後面是 所用時間長度。
【我只在這種路徑下嘗試成功。再建立一層目錄結構就無法實現】
通過包名。找到對應路徑:
然後找到對應的 檔案路徑:
F:\zhongruan\GarbageClear\bin
在cmd命令裡面:使用 java -verbosegc Garbage 命令,就可以得到如的結果。
刀下留人:
可以在Finalize()方法裡面實現 即將被殺死的對象的起死回生。
樣本:
而且 每次執行的結果不都一樣。
在命令列裡面恒只有一個
不恒了。。。笑哭,通常都是只有一個 執行了麼 。
並不知道是為什麼 10次以上都是這個結果。
執行的太快,還沒救活,就死了,所以需要系統沉睡一下Thread.sleep(1000)。
什麼是資料結構!!!
都忘記了。
定義的儲存資料的規則。
數組: 連續儲存資料的一種結構。
容器:list set map iterator
變數:嚴格來講不屬於資料結構,只是儲存資料的空間。只是一個類型
資料庫:是複雜的儲存資料的結構。是一個系統
數組 鏈表 隊列 棧
棧:像彈夾一樣,對於資料是先進後出。
鏈表結構: 單項鏈表 和雙向鏈表
節點: 指向下一個階段標示(引用變數)
數組和鏈表結構對比:數組遍曆效率高 增加刪除效率低
鏈表遍曆麻煩, 但是增加刪除 效率高。
老師的那個 鏈表 實在是 不敢恭維,有問題 絕對有問題:下面給出一個 我寫的感覺沒問題的鏈表:當然 棧也一併給出:
棧部分原始碼:
package MyStack;public class MyStack { private Object[] ob=new Object[2]; private int index=0; public void push(Object object){ if(index<ob.length){ ob[index++]=object; }else { Object[] newob = new Object[ob.length*2]; newob[index++]=object; for(int i=0;i<ob.length;i++){ newob[i]=ob[i]; } ob=newob; } } public Object pop(){ if(index==0){return null;} else{ return ob[--index]; } } public Object peek(){ if(index==0)return null; return ob[index-1]; } public int getSize(){ return index; }}
測試部分不再給出。
鏈表:
說實話面試的時候考察鏈表真的很帥,既考察了物件導向又考察了演算法。這就是當初我被刷下來的原因吧。所以 這次上完課還是好好琢磨了一下 鏈表,記得有時間實現鏈表的reverse。
有物件導向的思想,因為 它的基底是一個 節點對象:
package MyList;public class Node { private Object object; private Node next; public Node() { super(); } public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } public Node(Object object) { super(); this.object = object; } @Override public String toString() { return "Node [object=" + object + "]"; }}
然後是鏈表的方法:這也是人家真正想要考察的內容。
package MyList;/** * 在這鏈表中,第一個添加的元素作為頭結點,最後添加的作為尾節點 * @author Administrator * */public class MyList { private int size=0; private Node temp; private Node head; private Node tail; public void add(Object obj){ size++; temp= new Node(obj); if(tail==null){ tail = temp; head = temp; }else{ tail.setNext(temp); tail=temp; } } /** * 返回鏈表長度 * @return */ public int getSize(){ return size; } /** * 得到頭結點 * @return */ public Node getHead(){ if(head!=null) return head; return null; } /** * 得到尾節點 * @return */ public Node getTail(){ if(tail!=null) return tail; return null; } /** * 得到節點或者空 * @param obj * @return 返回這個值對應的節點 */ public Node find(Object obj){ //如果鏈表裡什麼都沒有那就返回null if(head==null) return null; //執行到這裡,說明鏈表不為空白 temp = head; if(temp.getObject().equals(4)){ return temp; }else{ return find(obj,temp); } } /** * 內部使用的用於找到如果head不為所要被尋找的元素的情況下所使用的遞迴函式 * 迴圈調用自身 * @param obj 要被尋找的項目 * @param temp 臨時變數,用以一個一個的往後面尋找節點 * @return 返回要被尋找的節點 */ private Node find(Object obj, Node temp) { temp=temp.getNext(); //先判斷一次是否相等 if(temp.getObject().equals(obj)){ return temp; }else{//不等的話,判斷是否進入temp 已經移到了 head 返回null,否則繼續執行本方法 if(temp==tail){ return null; }else{ return find(obj,temp); } } } //遍曆所有節點 public void lookoutAllNode(){ //如果頭結點為空白, if(head==null){ System.out.println("鏈表中尚未添加元素"); }else{ //否則一定裡面有元素 System.out.println(head); lookoutNext(head); } } //被封裝的用於迴圈調用的尋找下一個節點的方法 private void lookoutNext(Node head) { temp=head.getNext(); System.out.println(temp); if(temp==tail){ //遍曆結束 System.out.println("遍曆結束"); }else{ lookoutNext(temp); } } /** * 根據輸入的內容刪除對應元素 * @param object * @return */ public Node delete(Object object){ //沒有元素 if(head==null){ return null; }else{//有元素 //如果頭 就是的話 if(head.getObject().equals(object)){ //看看有幾個元素,有沒有必要順延? size--; temp=head; if(head==tail){//首尾相同 head=null; tail=null; return temp; }else{//頭不是尾 temp=head; head=head.getNext(); temp.setNext(null); return temp; } }else{//頭不是的話 return delete(object,head); } } } private Node delete(Object object, Node n) { //當前節點的下一個不可到達 if(n==tail){ return null; }else{//頭不是尾的話 if(n.getNext().getNext()!=null){//當前節點的下一個的下一個可到達 if(n.getNext().getObject().equals(object)){ size--; temp=n.getNext(); n.setNext(n.getNext().getNext()); temp.setNext(null); return temp; }else{ return delete(object,n.getNext()); } }else{//當前節點的僅下一個可到達 if(tail.getObject().equals(object)){//就是尾巴 size--; temp=tail; tail=n; n.setNext(null); return temp; }else{//不是尾巴 return null; } } } }}