AppGoatの概要
以下のコードを例に、プログラムで確保したメモリを解放せずにリターンするとメモリリークするから気を付けよう!!
という内容となっています。
→メモリを確保した後return 1している個所がそれです。
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int makeFile( char *fileName, int size )
{
FILE *fp;
char *pData;
// メモリを確保
pData = malloc( size );
if( pData == NULL )
return 1;
fp = fopen( fileName, "wb" );
if( fp == NULL )
return 1;
// ファイルに空白(0x20)を書き込み
memset( pData, 0x20, size );
fwrite( pData, size, 1, fp );
fclose( fp );
// メモリを解放
free( pData );
return 0;
}
決して悪い内容ではないのですが、
他の言語でのメモリリークとの付き合い方を纏めた方が良いなと感じたのでそちらにシフトします。
C#の場合
GCがよしなにやってくれる!!で終わらせる層が一定数いると思いますが、逆に言うとGCが求めるタイミングで動いてくれません。
.NETが管理していない、アンマネージリソースを扱う場合は自前で解放する必要があります。
アンマネージリソースの例:ファイル、ウィンドウ、ネットワーク接続、データベース接続など(いわゆるOSリソース)
詳しくは以下を参照ください。
https://docs.microsoft.com/ja-jp/dotnet/standard/garbage-collection/unmanaged
アンマネージドリソース以外だと、Subscribeなどを利用したイベント購読を行う場合もDisposeを行う必要があります。
補足:.Netには「メモリ使用量の分析」機能があるのでそちらに頼るのもありかもしれません。
https://docs.microsoft.com/ja-jp/visualstudio/profiling/analyze-memory-usage?view=vs-2019
Pythonの場合
Pythonは明示的にGCを利用する事が出来ます。
https://docs.python.org/ja/3/library/gc.html
コードサンプル
import gc
gc_test = ["gc del test"] * 100
del gc_test
gc.collect()
リファレンスを読み込むと、gc.garbageというGCが解放する事ができないオブジェクトのリストを返すメソッドが見つかったりと発見が多いです。
※Python 3.4以降、NULLでないtp_del スロットを持つ C 拡張型のインスタンスを使っている場合を除き、このリストはほとんど常に空であるとの事です。一般的なPythonの使い方をしている内は特段意識する必要はなく、自前拡張機能を作った時だけ気にすれば良さそうです。もしくはPythonアップデート時とか。
Goの場合
Goの場合、プログラムにdefer profile.Start(profile.MemProfile).Stop()を仕込んでmem.pprof(文字通り、メモリプロファイル)を生成し、
解析するのが一般的な手法なのかなと思います。
※違う等あれば、教えていただけると大変ありがたいです。。。
pprofを利用してメモリリークを調査した事例がこちら。
筆者の方はGoでblockchainを構築している方とのこと。
https://www.freecodecamp.org/news/how-i-investigated-memory-leaks-in-go-using-pprof-on-a-large-codebase-4bec4325e192/
Swiftの場合
クラスメソッド先生がXCodeで行うメモリリークチェック方法がまとめられていたのでリンクを張るだけにします。
https://dev.classmethod.jp/etc/ios-memory-leak-check-and-prevent-190508/
まとめ
各言語それぞれメモリリーク対策の色があって面白いです。
最近流行りの言語では
・標準ツールとして提供している
・IDEと一心同体の言語はIDE側にリッチな機能が備わっている
傾向があるのかなと感じました。
これから出てくる言語が流行るかどうかの指針になるかも。
一読くださりありがとうございました。