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
81
ガベージコレクション(GC)の基礎
オプト社内CS勉強会(第二回)の資料です。ガベージコレクションとは何か、について、馴染みのない向けに基本的な内容を説明したスライドです。
Opt Technologies
September 27, 2019
Tweet
Share
More Decks by Opt Technologies
See All by Opt Technologies
LL(1)構文解析の紹介
opttechnologies
0
280
Other Decks in Programming
See All in Programming
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
230
テスト駆動Kaggle
isax1015
1
530
What's new in AppKit on macOS 26
1024jp
0
150
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
660
AIエージェントはこう育てる - GitHub Copilot Agentとチームの共進化サイクル
koboriakira
0
720
ISUCON研修おかわり会 講義スライド
arfes0e2b3c
1
460
PipeCDのプラグイン化で目指すところ
warashi
1
300
MCPを使ってイベントソーシングのAIコーディングを効率化する / Streamlining Event Sourcing AI Coding with MCP
tomohisa
0
170
Porting a visionOS App to Android XR
akkeylab
0
670
「App Intent」よくわからんけどすごい!
rinngo0302
1
100
GPUを計算資源として使おう!
primenumber
1
220
Python型ヒント完全ガイド 初心者でも分かる、現代的で実践的な使い方
mickey_kubo
1
220
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
51k
Done Done
chrislema
184
16k
GraphQLとの向き合い方2022年版
quramy
49
14k
A better future with KSS
kneath
238
17k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Writing Fast Ruby
sferik
628
62k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
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");
より⾼度な話題へ より⾼度な話題へ
質問タイム 質問タイム どんどん質問してください