メモリリークとは何?発生する原因と発生を防ぐ方法について解説!
- プログラマー
- メモリリークが発生したら大変そうですね。ガベージコレクションが搭載されているからといって、メモリに関しての知識はおろそかにできないですよね。
- プロジェクト
リーダー - メモリはアプリケーション開発で重要な部分です。メモリ管理の知識がなくては良いアプリケーションはできないといっていいでしょう。
メモリリークとは何か
開発したプログラムを動作させる場合、作業領域であるメモリが必要になります。「メモリリーク(memory leak)」とは、プログラムによってメモリが枯渇してしまい、プログラムが実行できなくなる現象のことです。
メモリリークはプログラミングにおけるバグの1つとされており、実行中のプログラムがメモリ領域の解放を行わないまま放置してしまうことなどが原因で発生します。本記事ではメモリリークについてご紹介していきます。
メモリリークの4つの種類
メモリリークとひとことで言っても、メモリリークにはその発生原因によって4つの種類にわけることができます。具体的には、「LEAK_RETURN」「LEAK_ASSIGN」「LEAK_SCOPE」「LEAK_FREE」の4種類です。
ここではメモリリークの4つの種類についてそれぞれご紹介していきますので、ぜひ参考にしてみてはいかがでしょうか。
1:LEAK_RETURN
「LEAK_RETURN」とは、戻り値が無視されたことが原因で発生するメモリリークです。メモリリークはメモリブロックを指すポインタが何らかの原因によって失われることにより、動的に割り当てられたメモリブロックが解放できずに発生するエラーです。
LEAK_RETURNでは関数がメモリブロックを指すポインタを呼び出し元へ返した際に、ポインタが呼び出し元で無視されることによって発生します。
2:LEAK_ASSIGN
「LEAK_ASSIGN」とは、アドレスを上書きしたことが原因で発生するメモリリークです。LEAK_ASSIGNはポインタの再設定により、動的に振り分けられたメモリブロックが解放できなくなった際に発生します。
特に動的に割り当てられたブロックを指すポインタが上書きされてしまうと、LEAK_ASSIGNが発生してしまいます。
3:LEAK_SCOPE
「LEAK_SCOPE」とは、自動変数を失うことによって発生するメモリリークです。LEAK_SCOPEは特定のメモリブロックを指すポインタが関数を保持している場合に、ポインタをブローバル変数に保存せずに関数が終了することで自動変数が喪失した場合などに発生します。
また、ポインタを戻り値として戻さないまま関数が終了した場合にも発生します。
4:LEAK_FREE
「LEAK_FREE」とは、メモリを開放した際に発生するメモリリークです。メモリを開放する際に、解放したメモリブロックの中に別のメモリブロックを指すポインタが含まれている場合、LEAK_FREEが発生します。
メモリリークが発生してしまう原因とは
以下、メモリリークが発生する主な原因です。
1. 静的メンバーを利用している
staticキーワードがある場合は静的メンバーです。ガベージコレクションの対象となるのは、ヒープ領域にあるオブジェクトです。静的メンバーは対象外のため、静的領域に残り続けることになります。
2. Disposeメソッドを呼び出していない
3. 不完全なDisposeメソッドを利用している
4. WindowsフォームでBindingSourceコンポーネントの使い方を間違えている
メモリリーク発生頻度が少ない言語について
メモリリークの発生を防ぐ機能としては、.NET Frameworkなどに搭載されているガベージコレクションがあります。ガベージコレクションは高度なプログラミング言語に搭載されている機能で、関数型言語の多くはガベージコレクションを組み込んでいます。
また、Rubyなどの動的言語も、Javaのようなオブジェクト指向型言語もガベージコレクションを備えているケースが多いため、メモリリークの発生頻度は少ないと言えるでしょう。
ただし、すべての領域がガベージコレクションの対象というわけではないため、ガベージコレクションの対象外の領域ではメモリリークが発生することがあります。そのため、開発者にはメモリに関する知識が必要になります。
メモリリークの発生を防ぐ方法
開発者自身の手でメモリリークの発生を防ぐには、たとえば以下のような方法があります。
1. なるべくusing ステートメントを活用して、ステートメントが抜けたら自動でDisposeメソッドが発動されるようにする
2. オブジェクトがイベントを生成する必要がなくなったら、そのオブジェクトに対して、NullやNothingを設定する
3. 不要なイベントは呼び出さないようにする
4. オブジェクトの利用者側で破棄するのではなく、オブジェクトを作成した側で破棄するようにする
特にC言語などはガベージコレクションが搭載されていないため、開発者はメモリを開放するようにコーディングを行う必要があります。
ガベージコレクションについて
ガベージコレクションとは、不要なメモリを自動で解放する機能です。ガベージコレクションの働きによって、.NET Frameworkなどの高レベルの言語ではメモリリークは発生しにくいといわれています。
しかし、ガベージコレクションの対象外の領域も存在するため、その領域でメモリが自動的に解放されずにプログラムが実行されるたびにメモリ領域を占有すれば、メモリリークが発生することになります。
IDisposable・usingの使い方
IDisposableインターフェースでは「Dispose()」というメソッド内でリソースの解放を行います。たとえばリソース開放が必要なクラスを使用する場合、使い終わりのタイミングで「Dispose()」を呼びましょう。
また、usingは「Dispose()」を自動的に呼び出す構文です。usingのスコープから離れたタイミングや例外が発生した場合、自動的にDispose() を呼び出してくれます。
メモリリークを調査するツールとは?
メモリリークの調査にはフレームワークの「Valgrind」などが利用できます。Valgrindはメモリリークや不正なメモリアクセスを検出することができるため、Valgrindを活用することで開発者がデバッグ時に気付けないミスを発見することができます。
- プログラマー
- C#は、ガベージコレクションが搭載されていて良かったです。なければ解放漏れを起こして絶対にメモリリークを発生させてしまいそうです。
- プロジェクト
リーダー - C言語など、ガベージコレクションが搭載されていない言語で開発する場合、メモリの解放は開発者自身に委ねられます。.NET Frameworkではガベージコレクションが搭載されていますが、メモリの解放に関しては自らが意識してコーディングすることが必要ですよ。
メモリリークの発生を未然に防ごう!
メモリリークが基幹システムなどのサーバーで動作するプログラムで発生した場合、システム全体に影響を及ぼしてしまう事になります。そのため、開発者は仕様どおりに開発するのはもちろん、メモリリークについてもしっかりと意識し、発生を防ぐ必要があります。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
新着案件New Job
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅) -
PMO/東京都豊島区/【WEB面談可】/在宅勤務
月給55万~55万円東京都豊島区(池袋駅)