日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GC算法-标记压缩算法

發布時間:2024/8/23 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GC算法-标记压缩算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

概述

還記得標記清除和復制算法的問題么? 堆使用效率低和碎片化問題. 那么有沒有能夠利用整個堆, 有沒有內存碎片化問題的算法呢? 這就是標記壓縮算法了.

簡單來說, 標記壓縮算法就是將堆中的所有活動對象整體向左移, 將對象間的空隙消除.

在GC執行前的內存:

GC執行后的內存:

恩, 就是這么個意思.

實現

如何實現上面的操作呢? 首先, 要將所有活動對象標記出來. 這是標記階段, 跳過了, 跟標記清除一樣操作就行. (這里每個對象都有一個mark屬性, true為活動對象)

標記完了, 那就剩下壓縮操作了. 如何進行呢?

  • 遍歷堆, 將所有活動對象挪到左邊. 但是, 后面有對象引用了前邊的對象, 你就找不到新的指針了, 因為那塊地址很可能已經被覆蓋了.

  • ....

  • 最后想了想, 還是得老老實實地三步走:

  • 遍歷堆, 將所有對象通過計算得到新的地址并保存

  • 遍歷堆, 將所有子對象的地址更新為新的地址, 同時更新根集合中的指針.

  • 遍歷堆, 將對象集體遷移. 指針的問題都解決了, 可以將對象搬到新家了.

  • 步驟一: 計算所有對象的新地址

    // HEAP_START 是堆的開始位置, HEAP_END 是堆得結束位置 obj = HEAP_START newAddr = HEAP_START // 遍歷所有活動對象 while(obj < HEAP_END){// 非活動對象, 跳過if(obj.mark != true){obj += obj.size;continue;}// 記錄新的地址obj.newAddr = newAddrnewAddr += obj.size// 繼續遍歷obj += obj.size }

    這遍完后, 所有活動對象都保存了自己的新地址, 然后就可以將所有指針的地址進行更新了.

    步驟二: 更新所有指針

    // 更新根集合中的指針 for(obj in roots){obj = obj.newAddr } /* 更新所有活動對象的指針 當然, 這里也可以修改為遍歷所有活動對象, 并將指針進行更新. 但是會出現各種重復處理、指針覆蓋等問題, 就直接遍歷堆了. */ obj = HEAP_START while(obj < HEAP_END){if(obj.mark != true){obj += obj.size;continue;}// 更新子對象for(child in children){child = child.newAddr}obj += obj.size } ?

    至此, 所有指針都已經更新完畢, 但是, 對象還沒有移動. 只剩下最后一步了, 將對象按照步驟一的規律, 向左排排坐就好啦.

    步驟三: 遷移對象

    obj = newAddr = HEAP_START while(obj < HEAP_END){if(obj.mark != true) {obj += obj.size;continue;}// 將obj的數據復制到newAddr處copyData(newAddr, obj, obj.size);// 清空數據, 為下一次GC做準本newAddr.mark = false;newAddr.newAddr = null;// 遍歷下一個對象obj += obj.sizenewAddr += obj.size }

    至此, 實現基本完成. 創建對象分配內存的操作與復制算法一樣. 這個算法簡直是融合了標記清除和復制算法的優點, 解決了他們的問題, 不光堆的使用效率變高了, 而且也沒有內存碎片的問題了. 但是, 就是, 只不過要對堆進行三次遍歷而已. 不過沒關系啦, 畢竟有失才有得嘛. 不過是時間換空間了.

    而這, 也是標記壓縮算法最大的問題了, 執行時間太久了, 標記清除對堆進行一次遍歷, 而標記壓縮要進行三次. 三倍的時間. 可想而知.

    不過也有偉人說了, 算法沒有好不好, 只有是否適合. 這幾種可達性的算法各有優劣吧.

    標記壓縮的衍生

    Two-Finger算法

    將堆的遍歷次數減少到兩次.

    如上圖所示, 在第一次遍歷的時候, 指針1從前向后尋找空閑地址, 指針2從后向前尋找活動對象, 找到后在原地址中記錄新地址, 并將對象進行復制.

    第二次遍歷就可以將所有對象中的指針進行更新了.

    你也發現了, 這個算法如果不想發生內存碎片化, 那就只能令每個對象的空間都是相同的. 而事實上也確實是這樣. 強行規定每個對象都占用相同大小的空間, 我不知道這算法有什么應用場景. (原諒我的無知)

    其他

    還有一些其他的表格算法lmmixGC算法等, 因為這兩個我看的似懂非懂, 就不細說了.


    標記壓縮算法差不多就這么些. 告辭~~~

    總結

    以上是生活随笔為你收集整理的GC算法-标记压缩算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。