Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Game Boy Emulator作成で学んだ Golangのメモリライフタイム
Search
あつまるくん
July 29, 2024
Technology
1
350
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
計算機科学をRubyと歩む 〜DFA型正規表現エンジンをつくる~
ydah
3
190
技術以外の世界に『越境』しエンジニアとして進化を遂げる 〜Kotlinへの愛とDevHRとしての挑戦を添えて〜
subroh0508
1
380
Noを伝える技術2025: 爆速合意形成のためのNICOフレームワーク速習 #pmconf2025
aki_iinuma
2
2k
Sansanが実践する Platform EngineeringとSREの協創
sansantech
PRO
2
600
大企業でもできる!ボトムアップで拡大させるプラットフォームの作り方
findy_eventslides
1
500
著者と読み解くAIエージェント現場導入の勘所 Lancers TechBook#2
smiyawaki0820
12
5.9k
RAG/Agent開発のアップデートまとめ
taka0709
0
140
GitHub Copilotを使いこなす 実例に学ぶAIコーディング活用術
74th
3
1.3k
GitLab Duo Agent Platformで実現する“AI駆動・継続的サービス開発”と最新情報のアップデート
jeffi7
0
210
Ruby で作る大規模イベントネットワーク構築・運用支援システム TTDB
taketo1113
1
200
Playwrightのソースコードに見る、自動テストを自動で書く技術
yusukeiwaki
13
4.7k
ブロックテーマとこれからの WordPress サイト制作 / Toyama WordPress Meetup Vol.81
torounit
0
390
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.8k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
700
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.6k
How to Think Like a Performance Engineer
csswizardry
28
2.4k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
1
92
Unsuck your backbone
ammeep
671
58k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
It's Worth the Effort
3n
187
29k
Code Review Best Practice
trishagee
74
19k
RailsConf 2023
tenderlove
30
1.3k
GitHub's CSS Performance
jonrohan
1032
470k
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