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

.NET Frameworkには自動でメモリを解放してくれるガベージコレクションが搭載されています。しかし、このガベージコレクションはいつ解放されるかわかりません。なるべくメモリを解放するロジックはコーディングしておきたいところです。C#ではusingステートメントとDisposeメソッドがメモリ解放命令として用意されていますので、その両者の使用方法などをここで確認していきましょう。
- プログラマー
- ガベージコレクションが搭載されていてもやっぱりメモリ解放のコーディングは必要ですよね?
- プロジェクト
リーダー - そうですね。ガベージコレクションはいつ解放されるかわからないという特徴があります。そこはプログラマーたるもの自分でメモリの解放ロジックはコーディングする癖はつけたいところです。
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」です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
using System;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApp25
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
FileStream file = null;
try
{
//ファイルを開く
file = new FileStream(@"C:\WK\text_test.txt", FileMode.Open);
Console.WriteLine("ファイルをオープンしました");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
//破棄
file.Dispose();
Console.WriteLine("fileを破棄しました");
}
}
}
}
|
実行画面
ボタンを押下します。
コンソール確認
usingステートメントを用いたリソースの解放サンプルプログラム
以下、usingステートメントを利用したサンプルプログラムです。開発環境は上記と同じです。ご参考ください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
using System;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApp25
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
using (FileStream fs = new FileStream(@"C:\WK\text_test.txt", FileMode.Open))
{
Console.WriteLine("ファイルをオープンしました。");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
|
実行画面
ボタンを押下します。
コンソール確認
- プログラマー
- これからはusingステートメントやDisposeメソッドは積極的に活用して、メモリの解放はガベージコレクションだけに頼らずに行っていきます。
- プロジェクト
リーダー - ガベージコレクションですべてのメモリを解放できるかといったら、そうではありません。メモリを解放するコーディングの癖はつけておくことにこしたことはないでしょう。
メモリについての理解を深めることをおすすめします
C#はガベージコレクションが発動されるので、メモリリークが起こりにくい言語だといわれています。しかし、プログラムをコーディングする上でこのメモリについての理解は必要不可欠です。確かにメモリを理解していなくても、プログラムをコーディングすることは可能ですが、ユーザーが直接目に触れない部分で品質は下がっていることでしょう。今よりもワンランク上のプログラマーを目指すならば、プログラムを動作させる基本である、メモリについての理解を改めて深めるべきといえます。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)