Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
mallocしただけでメモリが確保できるって本当ですか?
MakKi
December 22, 2021
Programming
0
66
mallocしただけでメモリが確保できるって本当ですか?
AWS (t2.micro) デモバージョン
MakKi
December 22, 2021
Tweet
Share
More Decks by MakKi
See All by MakKi
君は古の言語M4を知っているか (LT)
makki_d
0
80
型パラメータが使えるようになったのでLINQを実装してみた
makki_d
2
750
ホットリロードツールの作り方
makki_d
0
520
JavaプログラムをGoに移植するためのテクニック――継承と例外
makki_d
1
1.2k
JavaプログラムをGoに移植するためのテクニック――継承と例外
makki_d
4
3.1k
mallocしただけでメモリが確保できるって本当ですか?
makki_d
4
510
パッケージ外から非公開フィールドを変更する方法.pdf
makki_d
0
210
とあるライブラリをGoに移植した結果……
makki_d
1
3.8k
バーコードリーダーになろう!
makki_d
0
81
Other Decks in Programming
See All in Programming
Azure Functionsをサクッと開発、サクッとデプロイ/vscodeconf2023-baba
nina01
1
320
Form実装基本を学び直してみた
hyugatsukui
0
220
あなたと 「|」 したい・・・
track3jyo
PRO
2
1k
[2023년 1월 세미나] 데이터 분석가 되면 어떤 일을 하나요?
datarian
0
530
Amazon QuickSightのアップデート -re:Invent 2022の復習&2022年ハイライト-
shogo452
0
200
中小企業開発事例から見るサーバーレス
seike460
PRO
4
1.5k
PHPアプリケーションにおけるアーキテクチャメトリクスについて / Architecture Metrics in PHP Applications
isanasan
1
200
Above All, Make It Fun! #fjordbootcamp / make it fun
kakutani
6
550
TokyoR#103_DataProcessing
kilometer
0
460
スタック・オーバーフローに コントリビュートしはじめて良かったこと🐣
takuyakikuchi
1
120
PHPDocにおける配列の型定義を少し知る
shimabox
1
120
Makuakeの認証基盤とRe-Architectureチーム
bmf_san
0
150
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
120
29k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
10
1.3k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
6
830
Large-scale JavaScript Application Architecture
addyosmani
499
110k
Design by the Numbers
sachag
271
18k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
15
1.2k
Debugging Ruby Performance
tmm1
67
11k
GitHub's CSS Performance
jonrohan
1020
430k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
22
1.7k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
63k
Thoughts on Productivity
jonyablonski
49
2.7k
Code Reviewing Like a Champion
maltzj
508
38k
Transcript
mallocしただけで メモリが確保できるって 本当ですか? KLab株式会社 牧内大輔
自己紹介 • 牧内大輔 ◦ Twitter: @makki_d ◦ Github: makiuchi-d •
KLab株式会社 ◦ スマホ向けオンラインゲームの会社 ◦ エンジニアリングマネージャー • 特徴 ◦ Linux使い(Kubuntu + Compiz) ◦ 仕事:オンライン対戦のネットワーク基盤とか ◦ 趣味:バーコード/QRコードライブラリをGoに移植 ▪ そういえば昨晩blog記事かきました • QRコードを1ピクセルずつ消していく闇のゲームの攻略法 • https://makiuchi-d.github.io/2021/12/22/yami-qrcode.ja.html
今日はmallocの話をします
C言語触ったことある人
mallocが何か知っている人
mallocについて • C標準ライブラリの関数 • メモリの動的割り当て #include <stdlib.h> void *malloc(size_t size);
mallocの使い方 • こんなコードを見たことがあると思います void *p = malloc(1000); if(p == NULL){
// メモリ確保失敗の処理 ... }
このプログラムを 見てください
#define MALLOC_COUNT 20 #define PAGE_SIZE 4096 int main() { char
*ptrs[MALLOC_COUNT] = {NULL}; int count = 0; int i; printf("start. pid=%d", getpid()); getchar(); for(i=0; i<MALLOC_COUNT; ++i){ ptrs[i] = (char *) malloc(100 * 1024 * 1024); if(ptrs[i] == NULL){ printf("malloc returns NULL\n"); break; } count++; printf("malloc: p[%d] = %p", i, ptrs[i]); getchar(); } printf("total %d MB allocated", count * 100); getchar(); for(i=0; i<count; ++i){ int t; for(t=0; t<100*1024*1024; t += PAGE_SIZE){ ptrs[i][t] = 0; } printf("touch %d MB", (i+1)100); getchar(); } for(i=0; i<count; ++i){ free(ptrs[i]); } return 0; }
#define MALLOC_COUNT 20 #define PAGE_SIZE 4096 int main() { char
*ptrs[MALLOC_COUNT] = {NULL}; int count = 0; int i; printf("start. pid=%d", getpid()); getchar(); for(i=0; i<MALLOC_COUNT; ++i){ ptrs[i] = (char *) malloc(100 * 1024 * 1024); if(ptrs[i] == NULL){ printf("malloc returns NULL\n"); break; } count++; printf("malloc: p[%d] = %p", i, ptrs[i]); getchar(); } printf("total %d MB allocated", count * 100); getchar(); for(i=0; i<count; ++i){ int t; for(t=0; t<100*1024*1024; t += PAGE_SIZE){ ptrs[i][t] = 0; } printf("touch %d MB", (i+1)100); getchar(); } for(i=0; i<count; ++i){ free(ptrs[i]); } return 0; } 100MBずつ20回malloc 失敗したらbreak 確保できたらアドレスを表示 確保した合計を表示 確保した領域に書き込み 書き込んだ領域のサイズ表示 メモリ解放
問題:何MB確保できるでしょうか • デモ用マシンについて ◦ AWS EC2 t2.micro Ubuntu20.04 LTS ◦
物理メモリ 1GB ▪ total 968MiB、free 700MiBちょっと ◦ スワップ領域 0 1. 700 MB 2. 900 MB 3. 2000 MB
動かしてみます
結果 • 2000MBまでmalloc成功 • この段階ではメモリ使用率は増えていない • 確保したメモリに書き込んではじめてメモリ使用率増加 • 800MBくらいでOOM-Killerによって強制終了
なぜこうなったのか
仮想アドレス空間 • プロセスから見えるメモリアドレス空間 ◦ ひと塊の大きなメモリに見える ◦ 物理メモリの大きさとは無関係 • プロセス毎に独立 ◦
他プロセスのメモリにアクセスできない • 物理メモリとのマッピングはOSが管理 ◦ CPUの機能(MMU)を利用 物理メモリ 仮想アドレス
mallocしたとき • 仮想アドレス空間を予約 ◦ このアドレスが戻り値 • 物理メモリへのマッピングはまだしない ◦ メモリ使用量は増えない 物理メモリ
仮想アドレス ?
書き込みしたとき • このとき初めて物理メモリにマッピング ◦ メモリ使用量増加 最終的に物理メモリが足りなくなり メモリを開放するために プロセスが殺されました(OOM-Killer) 物理メモリ 仮想アドレス
まとめ • mallocしただけでは物理メモリは確保されない • 戻り値チェックだけではメモリ不足を防げない • 大量にメモリを使うプログラムを書くときは気をつけましょう • 裏には複雑な仕組みが隠れていてコンピュータっておもしろい!
参考文献とか • [試して理解] Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識 ◦ 竹内 覚、2018、技術評論社 ◦ ISBN:
978-4774196077 ※今回のmallocの挙動は、glibcのmallocにおいて heapではなくpageからメモリ確保する場合のものです。 ※mallocはもっと複雑なことをやっているので、 興味のある人は小崎先生の動画を見ましょう。 https://www.youtube.com/watch?v=0-vWT-t0UHg