Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ガベージコレクション(GC)の基礎
Search
Opt Technologies
September 27, 2019
Programming
0
82
ガベージコレクション(GC)の基礎
オプト社内CS勉強会(第二回)の資料です。ガベージコレクションとは何か、について、馴染みのない向けに基本的な内容を説明したスライドです。
Opt Technologies
September 27, 2019
Tweet
Share
More Decks by Opt Technologies
See All by Opt Technologies
LL(1)構文解析の紹介
opttechnologies
0
290
Other Decks in Programming
See All in Programming
副作用と戦う PHP リファクタリング ─ ドメインイベントでビジネスロジックを解きほぐす
kajitack
3
510
11年かかって やっとVibe Codingに 時代が追いつきましたね
yimajo
1
230
MCPで実現できる、Webサービス利用体験について
syumai
7
2.3k
Vibe coding コードレビュー
kinopeee
0
400
Comparing decimals in Swift Testing
417_72ki
0
160
AIに安心して任せるためにTypeScriptで一意な型を作ろう
arfes0e2b3c
0
330
[DevinMeetupTokyo2025] コード書かせないDevinの使い方
takumiyoshikawa
2
250
Gemini CLIの"強み"を知る! Gemini CLIとClaude Codeを比較してみた!
kotahisafuru
3
910
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
110
リバースエンジニアリング新時代へ! GhidraとClaude DesktopをMCPで繋ぐ/findy202507
tkmru
7
1.7k
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_install_cms
rdlabo
0
420
SwiftでMCPサーバーを作ろう!
giginet
PRO
2
220
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
Agile that works and the tools we love
rasmusluckow
329
21k
Producing Creativity
orderedlist
PRO
346
40k
How to Think Like a Performance Engineer
csswizardry
25
1.8k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.5k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.6k
GraphQLとの向き合い方2022年版
quramy
49
14k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Transcript
ガベージコレクション(GC)の基礎 ガベージコレクション(GC)の基礎 CTO室 CTO室 ⽔島 宏太 ⽔島 宏太
⾃⼰紹介 ⾃⼰紹介 Twitter ID: GitHub: 社内でもkmizu 趣味: プログラミング⾔語|形式⾔語の⾃作 , etc.
@kmizu kmizu Onion Klassic Macro PEG
発表の構成 発表の構成 「当たり前」のGC GCの無い世界 完全な⾃動メモリ管理の不可能性 GCの基礎 参照カウント⽅式 マーク&スウィープ⽅式 より⾼度なGC 参考書籍
お願い お願い 発表の途中でも遠慮なく質問してください
「当たり前」のGC 「当たり前」のGC
GCは普通 GCは普通 現代の⾔語ではGCが無い⽅が少数派 Python, Ruby, Java, Scala, Go, etc. ⼀部の⾔語ではGCが無い
Rust, C(++)など システムプログラミングのため
GCサンプルコード GCサンプルコード 以下のJavaScriptプログラムは動作し続ける メモリが⾜りなくなることは無い GCがnew Object()で作ったメモリを回収する while(true) { const x
= new Object(); }
GCサンプルコード GCサンプルコード 以下のJavaScriptプログラムは死ぬ const buffer = [] while(true) { buffer.push(1);
} <--- Last few GCs ---> [2860:0x103003200] 938 ms: Scavenge 1148.7 (1181.9) -> 1148.7 (1 [2860:0x103003200] 1524 ms: Mark-sweep 1722.5 (1755.7) -> 1693.1 ...
GCサンプルコード(循環参照あり) GCサンプルコード(循環参照あり) 以下のJavaScriptプログラムも動作し続ける VBAとかPerlでは死ぬ class Ring { constructor(value, next) {
this.value = value; this.next = next; } } while(true) { const r = new Ring(1, null); r.next = r; //循環した参照 }
GCサンプルコード(循環参照あり) GCサンプルコード(循環参照あり) Excel VBA on macOS ぐんぐんメモリ消費量が増える GUIが固まる危険性があります さっき試した '
Ring.cls Public Link as Variant Dim p as Variant While 1 Set p = new Ring Set p.Link = p Wend
GCの無い世界 GCの無い世界
Cで動的バッファを作る Cで動的バッファを作る /* バッファを新規生成 */ Buffer* Buffer_new(void); /* バッファに要素を追加 */
void Buffer_append(Buffer* self, int content); /* バッファから要素を取り出す */ int Buffer_get(Buffer* self, int index); /* バッファに要素を設定 */ void Buffer_set(Buffer* self, int index, int content); /* バッファを解放 */ void Buffer_free(Buffer* self);
Cで動的バッファを使ってみる Cで動的バッファを使ってみる /* バッファを生成 */ Buffer* buffer = Buffer_new(); /*
10を追加 */ Buffer_append(buffer, 10); /* 10が表示される */ printf("%d\n", Buffer_get(buffer, 0)); /* 0番目に20を設定 */ Buffer_set(buffer, 0, 20); /* 20が表示される */ printf("%d\n", Buffer_get(buffer, 0)); /* バッファを解放 */ Buffer_free(buffer);
Cで動的バッファを解放し忘れてみる Cで動的バッファを解放し忘れてみる エラーが発⽣ 確保された領域が解放されないため メモリーリーク while(1) { Buffer* buf =
Buffer_new(); } $ ./buffer ... *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug buffer(57390,0x7fffa9cff380) malloc: *** mach_vm_map(size=40001536) f
Cプログラミングの難しさ Cプログラミングの難しさ メモリ安全でない GCが無い ⼿動で確保した領域を解放する必要 処理系がいい感じでメモリを管理して欲しい︕ or メモリリークがあるか判定して欲しい︕
脇道: Boehm GC 脇道: Boehm GC C⾔語⽤のGCライブラリ GC_MALLOC() で確保した領域をGCしてくれる 以下のプログラムが死なない
https://en.wikipedia.org/wiki/Boehm_garbage_collector while(1) { char *p = GC_malloc(1000000); }
完全な⾃動メモリ管理 完全な⾃動メモリ管理 プログラムの不可能性 プログラムの不可能性
完全なメモリリーク判定プログラムは書け 完全なメモリリーク判定プログラムは書け ない ない 「健全かつ完全な」メモリリーク判定関数 has_memory_leak が書けると仮定する has_memory_leak が書けると⽭盾するので書けない int
has_memory_leak(char* program, char* input) void run(char* program, char* input) { if(has_memory_leak(program, input)) { return; } else { /*メモリリークが発生しないはずなのにする!*/ malloc(sizeof(int)); } } int main(char** input) { run(to_string(run), input[0]); return 0; }
完全なメモリ解放処理挿⼊プログラムも書 完全なメモリ解放処理挿⼊プログラムも書 けない けない has_memory_leak が書けないのと同じ理屈 こういう問題を決定不能 (undecidable) と呼ぶ 決定不能な問題(で有⽤なもの)は凄く多い
⾊々な型チェックに関する問題 System F<: DOT計算 ,etc. ウイルスが⼊っているかを判定する ⽂脈⾃由以上の⾔語に関する様々な判定問題 , etc.
決定不能問題の取り扱い 決定不能問題の取り扱い 現実的な解法(1): 保守的(conservative)な解法 いくらかメモリ解放処理を挿⼊し忘れてもいい 本来型がついて欲しいプログラムのいくつかには型 が付かない 現実的な解法(2): ヒューリスティクス ウイルス検知プログラム
誤検知も⾒逃しもあるが、精度はそれなり
GCの基礎 GCの基礎
GCの保守性 GCの保守性 GCはいい感じに不要なメモリを解放してくれる GCは保守的(conservative) 必要なオブジェクトを絶対に解放しない 不要なオブジェクトを解放し忘れることがある GCがある⾔語でも「メモリリーク」はある 本来の「メモリリーク」と意味が違うが
GC: なぜ動く︖ GC: なぜ動く︖ 変数からオブジェクトのつながりを追跡できればいい let x = new Object();
x = null; x Object x Object
参照カウント⽅式 参照カウント⽅式 オブジェクトにカウンタを持たせる いくつの変数から指されているか カウントが0になれば解放可能
let x = new Object(); x Object[count=1] let y =
x; x Object[count=2] y y = null; x = null; x Object[count=0] y
参照カウント⽅式の限界 参照カウント⽅式の限界 参照が循環すると詰む let x = new Ring(1, null); x.next
= x; x = null; x Ring[count=1]
参照カウント⽅式の利点 参照カウント⽅式の利点 実装が簡単 オブジェクトにカウンタを埋め込む カウンタを上下させる GCによる停⽌が(あまり)発⽣しない
参照カウント⽅式の⾔語処理系 参照カウント⽅式の⾔語処理系 ⾔語仕様でGC⽅式が決まっているわけではない Javaで参照カウント⽅式のGCも仕様上はOK 昔のMicroso JVMがそうだった記憶(曖昧) Perl 5 VBA VB
6までも同様 Swi , Objective-C ARC (Automatic Reference Counting) Python マーク&スウィープ⽅式と併⽤
マーク&スウィープ⽅式 マーク&スウィープ⽅式 スタックやレジスタ上にある変数を管理 ルートセット と呼ばれる ルートセットから到達可能なオブジェクトのみが⽣き ている それ以外は回収可能
ホワイトボードによる説明 ホワイトボードによる説明 var x = new Ring(1, null); var y
= x; x.next = x; x = null; y = null;
マーク&スウィープ⽅式の利点 マーク&スウィープ⽅式の利点 参照が循環していてもいい OOPとかFPではよくある 参照カウント⽅式よりも性能がいい(ことが多い) スループット VS. レイテンシ
マーク&スウィープ⽅式の⽋点 マーク&スウィープ⽅式の⽋点 GCのための停⽌時間が⻑くなることがある オブジェクトのグラフをたどるため 参照カウント⽅式だと短い 処理系がスタックやレジスタ上の変数を管理する必要
より⾼度なGC より⾼度なGC 世代別GC 管理領域を複数に分割する 並列GC たどりや掃除を並列に⾏う その他⾊々
GCがある⾔語でのメモリリーク GCがある⾔語でのメモリリーク ほぼどんな⾔語でも起こる const global = new Object(); console.log("start"); for(leti
= 0; i < 10000; i++) { console.log(i); } // globalは決して使われないが解放されない console.log("end");
より⾼度な話題へ より⾼度な話題へ
質問タイム 質問タイム どんどん質問してください