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
Game Boy Emulator作成で学んだ Golangのメモリライフタイム
Search
あつまるくん
July 29, 2024
Technology
0
240
Game Boy Emulator作成で学んだ Golangのメモリライフタイム
DMM.go#8で登壇した際の発表資料です
connpass
-
https://dmm.connpass.com/event/322113/
あつまるくん
July 29, 2024
Tweet
Share
Other Decks in Technology
See All in Technology
AWS アーキテクチャ作図入門/aws-architecture-diagram-101
ma2shita
30
11k
AIのAIによるAIのための出力評価と改善
chocoyama
2
580
2025-06-26_Lightning_Talk_for_Lightning_Talks
_hashimo2
2
100
ひとり情シスなCTOがLLMと始めるオペレーション最適化 / CTO's LLM-Powered Ops
yamitzky
0
440
20250625 Snowflake Summit 2025活用事例 レポート / Nowcast Snowflake Summit 2025 Case Study Report
kkuv
1
330
250627 関西Ruby会議08 前夜祭 RejectKaigi「DJ on Ruby Ver.0.1」
msykd
PRO
2
330
Wasm元年
askua
0
150
Oracle Cloud Infrastructure:2025年6月度サービス・アップデート
oracle4engineer
PRO
2
280
AIの最新技術&テーマをつまんで紹介&フリートークするシリーズ #1 量子機械学習の入門
tkhresk
0
140
mrubyと micro-ROSが繋ぐロボットの世界
kishima
2
350
【TiDB GAME DAY 2025】Shadowverse: Worlds Beyond にみる TiDB 活用術
cygames
0
1.1k
Kotlin Coroutine Mechanisms: A Surprisingly Deep Rabbithole
amanda_hinchman
2
100
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
337
57k
Statistics for Hackers
jakevdp
799
220k
For a Future-Friendly Web
brad_frost
179
9.8k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
Building an army of robots
kneath
306
45k
Fireside Chat
paigeccino
37
3.5k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.5k
Code Reviewing Like a Champion
maltzj
524
40k
The Cult of Friendly URLs
andyhume
79
6.5k
Become a Pro
speakerdeck
PRO
28
5.4k
Transcript
© DMM Game Boy Emulator作成で学んだ Golangのメモリライフタイム ~Boot ROMの起動~ DMM.go
#8
© DMM 自己紹介 清水 諄孔 GitHub: atsumarukun 入社: 2024年 新卒入社
所属: 開発統括本部 テックリード室 趣味: PCに触れること OS開発経験 2
© DMM 目的 Golangにおけるメモリのライフタイムを知る 3
© DMM 前提知識 4 メモリは1byte(8bit)単位で区切られており、 アドレスはメモリ内部での場所(何番目の領域か)を指します。 アドレスは16進数で表記する 1byte 1byte 1byte
1byte 0x00 0x01 0x02 0x03
© DMM 前提知識 5 ポインタは定数や変数が保存されている アドレスを保持する変数のことです。 variable1 variable2 0x00 0x01
0x02 2byte以上ある変数のポインタは先頭アドレスになる variable2 0x03
© DMM 内容 やったこと ❶ ❷ 通常のメモリ管理 ❸ Golangのメモリ管理 6
© DMM 内容 やったこと ❶ ❷ 通常のメモリ管理 ❸ Golangのメモリ管理 7
© DMM BootROMを起動 8
© DMM 開発の流れ 1. 各種メモリを実装 2. CPUを実装 3. PPUを実装 4.
LCDを実装 5. サイクルベースでエミュレータを実装 6. カートリッジを実装 7. Joypadを実装 8. APUを実装 9
© DMM 開発の流れ 1. 各種メモリを実装 2. CPUを実装 3. PPUを実装 4.
LCDを実装 5. サイクルベースでエミュレータを実装 6. カートリッジを実装 7. Joypadを実装 8. APUを実装 10
© DMM デバイスの管理 CPUにおけるデバイスの管理方法を知っていますか? 11
© DMM デバイスの管理 I/OデバイスはMMIOというアドレス空間で管理されます。 これにより、CPUはメモリと同じようにI/Oデバイスを操作できます。 12
© DMM デバイスの管理 CPUがメモリやI/Oをアドレス空間で認識するのであれば これらの変数をStatic領域に保存する必要があるのでは...? 13
© DMM 内容 やったこと ❶ ❷ 通常のメモリ管理 ❸ Golangのメモリ管理 14
© DMM メモリ領域の種類 メモリ領域には以下の4種類があります。 このうち、ヒープ領域とスタック領域は動的に確保されます。 テキスト領域 スタティック領域 ヒープ領域 スタック領域 15
© DMM テキスト領域 テキスト領域には、コンパイルされたプログラムが格納されます。 CPUが格納された機械語の命令を読むことでプログラムが実行されます。 16
© DMM スタティック領域 スタティック領域には静的変数が格納されます。 グローバル変数やstatic装飾子を用いて定義した変数が格納されています。 17
© DMM ヒープ領域 ヒープ領域は動的に管理されます。 プログラマが明示的に確保、解放を行う必要があります。 18
© DMM スタック領域 スタック領域は、スタック上にメモリを確保していきます。 関数内で定義された変数は関数終了時に自動削除されます。 argument1 argument2 variable func stack(argument1
uint8, argument2 uint8) { var variable uint8 // 何かしらの処理 } 19
© DMM スタック領域 まず、関数の引数をスタック領域に格納します。 argument1 argument2 variable func stack(argument1 uint8,
argument2 uint8) { var variable uint8 // 何かしらの処理 } 20
© DMM スタック領域 その後、関数内で定義されている変数を 順番に格納していきます。 argument1 argument2 variable func stack(argument1
uint8, argument2 uint8) { var variable uint8 // 何かしらの処理 } 21
© DMM スタック領域 関数の実行が終わると、スタック領域から削除されます。 argument1 argument2 variable func stack(argument1 uint8,
argument2 uint8) { var variable uint8 // 何かしらの処理 } 22
© DMM 内容 やったこと ❶ ❷ 通常のメモリ管理 ❸ Golangのメモリ管理 23
© DMM Golangにおけるメモリ管理 Golangでは、変数を関数に渡すと自動的にヒープ領域に移動します。 そのため、関数終了時に値が削除されることはありません。 go build -gcflags -m main.goでわかる通り、コンパイル時に移動される
var variable uint8 = 1 // <- この時点ではスタック領域 fmt.Println(variable) // <- ここでヒープ領域に移動 24
© DMM メモリ領域 メモリ領域は右の図のようになっています。 ヒープ領域 ↓ ↑ スタック領域 スタティック領域 テキスト領域
var variable uint8 = 1 fmt.Println(variable) 25
© DMM メモリ領域 静的変数を定義した段階では、 スタック領域に確保されます。 ヒープ領域 ↓ ↑ スタック領域 スタティック領域
テキスト領域 var variable uint8 = 1 fmt.Println(variable) 26
© DMM メモリ領域 関数に渡されると、コンパイル時に ヒープ領域へ移動されます。 ヒープ領域 ↓ ↑ スタック領域 スタティック領域
テキスト領域 var variable uint8 = 1 fmt.Println(variable) 27
© DMM サンプルプログラム uint8_t* address; void function(void) {
uint8_t variable = 1; printf("%p\n", &variable); // -> 0xffffe469565f address = &variable; } int main(void) { function(); printf("%p\n", address); // -> 0xffffe469565f printf("%d\n", *address); // -> 102 return 0; } 関数内のアドレスと、グローバル変数のポ インタの値は等しくなります。 アドレスの値を見ると、1になっていないこ とがわかります。 C言語 28
© DMM サンプルプログラム var address *uint8 func main() {
(func() { var variable uint8 = 1 fmt.Printf("%p\n", &variable) // -> 0xffffe469565f address = &variable })() fmt.Printf("%p\n", address) // -> 0xffffe469565f fmt.Println(*address) // -> 1 } C言語同様、アドレスの値は関数内とグ ローバル変数で等しくなります。 しかし、アドレスの値を見ると1のままであ ることがわかります。 Go言語 29
© DMM 依存関係の逆転 type AccountRepository Interface {} type Account struct
{ db *sql.DB } func NewAccount(db *sql.DB) AccountRepository { return &Account{ db: db, } } 関数の戻り値で直接構造体のアドレスを返 すことができます。 これにより、関数の戻り値に Interfaceを指定が可能になります。 30
© DMM まとめ Go言語ではライフタイムの管理を自動的に行ってくれるため、 プログラマがメモリ管理を意識しなくても開発できるようになっている ことがわかりました。 31
© DMM ご清聴ありがとうございました 32