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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

V8 垃圾回收

發布時間:2025/3/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 V8 垃圾回收 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自: https://github.com/yjhjstz/deep-into-node

垃圾回收器是一把十足的雙刃劍。好處是簡化程序的內存管理,內存管理無需程序員來操作,由此也減少了長時間運轉的程序的內存泄漏。然而無法預期的停頓,影響了交互體驗。本文從 V8 (node.js runtime) 的角度分析垃圾回收策略。

基本概念

垃圾回收器解決基本問題就是,識別需要回收的內存。一旦辨別完畢,這些內存區域即可在未來的分配中重用,或者是返還給操作系統。一個對象當它不是處于活躍狀態的時候它就死了。一個對象處于活躍狀態,當且僅當它被一個根對象或另一個活躍對象指向。根對象被定義為處于活躍狀態,是瀏覽器或V8所引用的對象。比如說全局對象屬于根對象,因為它們始終可被訪問;瀏覽器對象,如DOM元素,也屬于根對象,盡管在某些場合下它們只是弱引用。

堆的構成

在深入研究垃圾回收器的內部工作原理之前,首先來看看堆是如何組織的。V8將堆分為了幾個不同的區域:

新生區:大多數對象開始時被分配在這里。新生區是一個很小的區域,垃圾回收在這個區域非常頻繁,與其他區域相獨立。

老生指針區:包含大多數可能存在指向其他對象的指針的對象。大多數在新生區存活一段時間之后的對象都會被挪到這里。

老生數據區:這里存放只包含原始數據的對象(這些對象沒有指向其他對象的指針)。字符串、封箱的數字以及未封箱的雙精度數字數組,在新生區經歷一次 Scavenge 后會被移動到這里。

大對象區:這里存放體積超過1MB大小的對象。每個對象有自己mmap產生的內存。垃圾回收器從不移動大對象。

Code區:代碼對象,也就是包含JIT之后指令的對象,會被分配到這里。

Cell區、屬性Cell區、Map區:這些區域存放Cell、屬性Cell和Map,每個區域因為都是存放相同大小的元素,因此內存結構很簡單。

如上圖:在 node-v4.x 之后,區域進行了合并為:新生區,老生區,大對象區,Map區,Code區

有了這些背景知識,我們可以來深入垃圾回收器了。

識別指針

垃圾回收器面臨的第一個問題是,如何才能在堆中區分指針和數據,因為指針指向著活躍的對象。大多數垃圾回收算法會將對象在內存中挪動(以便減少內存碎片,使內存緊湊),因此即使不區分指針和數據,我們也常常需要對指針進行改寫。
V8采用了標記指針法:這種方法需要在每個指針的末位預留一位來標記這個字代表的是指針或數據。

寫屏障

如果新生區中某個對象,只有一個指向它的指針,而這個指針恰好是在老生區的對象當中,我們如何才能知道新生區中那個對象是活躍的呢? 為了解決這個問題,實際上在寫緩沖區中有一個列表 store-buffer{.cc,.h,-inl.h},列表中記錄了所有老生區對象指向新生區的情況。新對象誕生的時候,并不會有指向它的指針,而當有老生區中的對象出現指向新生區對象的指針時,我們便記錄下來這樣的跨區指向。由于這種記錄行為總是發生在寫操作時,它被稱為寫屏障.

垃圾回收三部曲

Stop-the-World 的GC包括三個主要步驟:

  • 枚舉根節點引用;
  • 發現并標記活對象;
  • 垃圾內存清理
  • 分代回收在 V8中分為Scavenge, Mark-Sweep。

    • Scavenge: 當分配指針達到了新生區的末尾,就會有一次清理。
    • Mark-Sweep: 對于活躍超過2個小周期的對象,則需將其移動至老生區, 當老生區有足夠多的對象時才會觸發。

    Scavenge

    void Heap::Scavenge() {RelocationLock relocation_lock(this);AlwaysAllocateScope scope(isolate());gc_state_ = SCAVENGE;// Clear descriptor cache.isolate_->descriptor_lookup_cache()->Clear();// Used for updating survived_since_last_expansion_ at function end.intptr_t survived_watermark = PromotedSpaceSizeOfObjects();SelectScavengingVisitorsTable();PrepareArrayBufferDiscoveryInNewSpace();// Flip the semispaces. After flipping, to space is empty, from space has// live objects.new_space_.Flip(); // 交換 SemiSpacenew_space_.ResetAllocationInfo(); // 重設分配指針Address new_space_front = new_space_.ToSpaceStart();promotion_queue_.Initialize(); // 晉升隊列ScavengeVisitor scavenge_visitor(this); // Scavenge迭代器// Copy roots. 枚舉跟對象IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); // Copy objects reachable from the old generation.{StoreBufferRebuildScope scope(this, store_buffer(),&ScavengeStoreBufferCallback);store_buffer()->IteratePointersToNewSpace(&ScavengeObject);}// Copy objects reachable from the encountered weak collections list.scavenge_visitor.VisitPointer(&encountered_weak_collections_);// Copy objects reachable from the encountered weak cells.scavenge_visitor.VisitPointer(&encountered_weak_cells_);// Copy objects reachable from the code flushing candidates list.MarkCompactCollector* collector = mark_compact_collector();if (collector->is_code_flushing_enabled()) {collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);}// DoScavenge 處理晉升new_space_front = DoScavenge(&scavenge_visitor, new_space_front);while (isolate()->global_handles()->IterateObjectGroups(&scavenge_visitor, &IsUnscavengedHeapObject)) {new_space_front = DoScavenge(&scavenge_visitor, new_space_front);}isolate()->global_handles()->RemoveObjectGroups();isolate()->global_handles()->RemoveImplicitRefGroups();isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(&IsUnscavengedHeapObject);isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(&scavenge_visitor);new_space_front = DoScavenge(&scavenge_visitor, new_space_front);UpdateNewSpaceReferencesInExternalStringTable(&UpdateNewSpaceReferenceInExternalStringTableEntry);promotion_queue_.Destroy();incremental_marking()->UpdateMarkingDequeAfterScavenge();ScavengeWeakObjectRetainer weak_object_retainer(this);ProcessYoungWeakReferences(&weak_object_retainer);DCHECK(new_space_front == new_space_.top());// Set age mark.new_space_.set_age_mark(new_space_.top());new_space_.LowerInlineAllocationLimit(new_space_.inline_allocation_limit_step());FreeDeadArrayBuffers(true);// Update how much has survived scavenge.IncrementYoungSurvivorsCounter(static_cast<int>((PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));gc_state_ = NOT_IN_GC; }

    這個算法大致是,新生區被劃分為兩個等大的SemiSpace:出區、入區。絕大多數內存的分配都會在出區發生(但某些特定類型的對象,如可執行的代碼對象是分配在老生區的),當出區耗盡時,我們交換出區和入區(這樣所有的對象都歸屬在入區當中),然后將入區中活躍的對象復制至出區或晉升到老生區中,其中標記的過程實際是深度優先搜索。

    “標記-清除”算法

    void MarkCompactCollector::CollectGarbage() {DCHECK(state_ == PREPARE_GC);MarkLiveObjects(); //枚舉并標記活對象DCHECK(heap_->incremental_marking()->IsStopped());// ClearNonLiveReferences can deoptimize code in dependent code arrays.// Process weak cells before so that weak cells in dependent code// arrays are cleared or contain only live code objects.ProcessAndClearWeakCells();ClearNonLiveReferences();ClearWeakCollections();heap_->set_encountered_weak_cells(Smi::FromInt(0));ClearInvalidStoreAndSlotsBufferEntries();SweepSpaces(); // 按不同的空間劃分清理Finish();if (marking_parity_ == EVEN_MARKING_PARITY) {marking_parity_ = ODD_MARKING_PARITY;} else {DCHECK(marking_parity_ == ODD_MARKING_PARITY);marking_parity_ = EVEN_MARKING_PARITY;} }

    Scavenge算法對于快速回收、緊縮小片內存效果很好,但對于大片內存則消耗過大。頻繁的拷貝對于 CPU 是不可承受之重。老生區包含有上百MB的數據,對于這么大的區域,我們采取“標記-清除”算法與“標記-緊縮”算法。

    標記算法執行完畢后,我們可以選擇清理或是緊縮,這兩個算法都可以回收內存。

    • 清理算法非常簡單,只需遍歷頁的位圖,搜索連續的死對象釋放,時間久了會形成內存碎片。
    • 緊縮算法會嘗試將對象從碎片頁(包含大量小空閑內存的頁)中遷移整合在一起,來釋放內存。這些對象會被遷移到另外的頁上,因此也可能會新分配一些頁。alinode 對此策略進行了優化,使用 alinode runtime 即可享受到。

    總結

    垃圾回收非常復雜,alinode 提供了詳細的 GC 監控,幫助您分析把控性能。

    總結

    以上是生活随笔為你收集整理的V8 垃圾回收的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 依人久久| 久久久久草 | 亚洲欧美日韩精品久久亚洲区 | 天堂一区在线观看 | 免费一区二区在线观看 | 综合久久综合久久 | 涩涩视频网站在线观看 | 最全aⅴ番号库 | 日韩视频欧美视频 | 男性裸体全身精光gay | 日本在线色 | 日韩中文字幕国产 | 污污污污污污www网站免费 | 裸体男女树林做爰 | 国产a线 | 亲子乱一区二区三区 | 久久久99精品免费观看 | 国产精品免费一区 | 95香蕉视频 | 免费毛片网站在线观看 | 男人的天堂va | 精品日韩中文字幕 | 国产一页 | www一区| www日韩 | 毛片网在线观看 | 你懂的在线观看视频 | 欧美日韩综合 | 国产wwwxxx| 自拍偷拍福利 | 日本一区成人 | 亚洲91网 | 成人免费看毛片 | 国产精品一二三四区 | 亚洲一区二区黄片 | 免费看片亚洲 | 日本黄色免费在线观看 | 天堂在线免费观看视频 | 椎名由奈av一区二区三区 | 婷婷导航| www.777奇米影视 | 欧美影院一区 | 相亲对象是问题学生动漫免费观看 | 红桃成人网 | 91精品欧美一区二区三区 | 中文字幕在线乱 | 天堂网视频在线观看 | av电影在线不卡 | 国产精品91视频 | 啪啪导航 | 国产成人精品免高潮费视频 | 污视频免费看 | 在线日韩精品视频 | av网址网站 | 免费看黄在线看 | 天天做天天摸天天爽天天爱 | 婷婷九月综合 | 北岛玲在线 | 老外毛片 | 欧美性视频一区二区三区 | 中文天堂在线资源 | 欧美在线观看一区二区三区 | 风间由美在线视频 | 免费三片在线播放 | 人体裸体bbb欣赏 | 男人天堂999 | 久久精品国产亚洲AV无码麻豆 | 日韩不卡免费 | 亚洲人成网站999久久久综合 | 一级黄色在线视频 | 91视频高清 | 久久久视频6r | 亚洲一区二区精品视频 | 筱田优av| 亚洲高清在线免费观看 | 亚洲在线视频免费观看 | 亚a在线| 国产一区二区三区在线观看免费 | 日本色中色 | 午夜影音 | 天天av综合 | 亚洲巨乳av | jjzz国产 | 大学生三级中国dvd 日韩欧美一区二区区 | 中文自拍| 欧美骚少妇 | 丝袜av电影 | 久久免费视屏 | 中文字幕影片免费在线观看 | 黄色三级三级三级 | 少妇人禽zoz0伦视频 | 久久久久国色av免费观看性色 | 丝袜调教91porn | 久久精品黄aa片一区二区三区 | 国产精品久久久久久久久久久久久 | xxxx日本黄色 | 国产九色av | 欧美20p| 天天看天天爽 |