.net column

.NET開発者のためのブログメディア
ゴミ箱

C#のusingステートメントでリソースの解放【Disposeとの違いとは】

2020年03月17日

.NET Frameworkには自動でメモリを解放してくれるガベージコレクションが搭載されています。しかし、このガベージコレクションはいつ解放されるかわかりません。なるべくメモリを解放するロジックはコーディングしておきたいところです。C#ではusingステートメントとDisposeメソッドがメモリ解放命令として用意されていますので、その両者の使用方法などをここで確認していきましょう。

PG
ガベージコレクションが搭載されていてもやっぱりメモリ解放のコーディングは必要ですよね?
PL
そうですね。ガベージコレクションはいつ解放されるかわからないという特徴があります。そこはプログラマーたるもの自分でメモリの解放ロジックはコーディングする癖はつけたいところです。

Disposeメソッドとは

データベースやファイルなどの外部リソースは、ガベージコレクションの対象外です。使い終えたらそのリソースは解放するようにしましょう。不要な外部リソースは解放しないとメモリリークを発生させる原因となってしまいます。

メモリリークが発生してしまうと、サーバーを再起動しないといけなくなります。そうならないためにも、外部リソースの解放は必ず忘れずに行いましょう。その際に利用する代表的なメソッドが、Disposeメソッドです。明示的にメソッドを記述してあげて、解放することを心がけるようにしましょう。

リソースの解放が必要かどうかは、インスタンスに「.」をつけてDisposeメソッドの有無で確認することが可能です。たいていの場合はtry~catch~finallyで処理を記述し、finally句にDisposeメソッドをコーディングします。

なぜならば、解放対象インスタンスのtry~catchで囲んでいない箇所でシステムエラーが発生して処理が終わると、Disposeメソッドが呼ばれないことがあるからです。当然ですが、呼ばれないとリソースの解放は行ってくれませんので、確実に呼ばれるfinally句にコーディングするのが一般的です。

usingステートメントの概要

対してusingステートメントとは、上記で説明したfinally句にDisposeメソッドをコーディングするのと同様の処理を簡単にできる命令です。finally句をわざわざコーディングしなくても、usingステートメントをコーディングしていれば、usingステートメントを抜けるタイミングでDisposeメソッドが自動で発動されるようになります。この記述を行うことで、Disposeメソッドの呼び忘れがなくなるメリットがあり、使用が推奨されている命令のひとつです。

ただし、usingステートメントが利用できるのは、インスタンスの確保と解放がひとつのメソッド内で行われる場合のみです。

プログラマー各自にメモリの解放を託すことは、それだけ解放漏れのリスクも上がります。メモリリークは絶対に発生させてはいけません。usingステートメントを利用することは、開発規約などでも記載しておくべきでしょう。

捕捉として、C#ではプログラム上部にusingでネームスペースを省略してコーディングするための命令も存在しています。今回紹介したメモリを解放するためのusingステートメントとはまったくの別物ですので注意してください。

Disposeメソッドを用いたリソースの解放サンプルプログラム

以下、Disposeメソッドを利用したサンプルプログラムです。開発環境は、Visual Studio Community 2017のWindows Formsで開発を行っています。また、.NET Frameworkのバージョンは「4.6」です。

実行画面
ボタンを押下します。
Dispose実行ボタン

コンソール確認
Dispose実行結果

usingステートメントを用いたリソースの解放サンプルプログラム

以下、usingステートメントを利用したサンプルプログラムです。開発環境は上記と同じです。ご参考ください。

実行画面
ボタンを押下します。
using実行ボタン

コンソール確認
using実行結果

PG
これからはusingステートメントやDisposeメソッドは積極的に活用して、メモリの解放はガベージコレクションだけに頼らずに行っていきます。
PL
ガベージコレクションですべてのメモリを解放できるかといったら、そうではありません。メモリを解放するコーディングの癖はつけておくことにこしたことはないでしょう。

メモリについての理解を深めることをおすすめします

C#はガベージコレクションが発動されるので、メモリリークが起こりにくい言語だといわれています。しかし、プログラムをコーディングする上でこのメモリについての理解は必要不可欠です。確かにメモリを理解していなくても、プログラムをコーディングすることは可能ですが、ユーザーが直接目に触れない部分で品質は下がっていることでしょう。今よりもワンランク上のプログラマーを目指すならば、プログラムを動作させる基本である、メモリについての理解を改めて深めるべきといえます。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

求人一覧

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)