ファイナライザを理解する ~ ファイナライザに起因するトラブルを避けるために ~ 2013 年 11 月 25 日 橋口雅史 Java アプリケーションでファイナライザ (finalize() メソッド ) を使用したことがあるプログラマーは多いと思います しかし ファイナライザの仕組みや注意点につ

Similar documents
21 章のお話

HashMapからConcurrentHashMapへの移行

PowerPoint プレゼンテーション

<基礎領域>

Java の ConcurrentHashMap における同期化 バッドケースとその対処法 2013 年 9 月湊隆行 1. はじめに表 1.1 に示すように Java の Collections Framework には 3 つの世代があります バージョン 1.0 から存在するレガシー API バ

開発・運用時のガイド JDK8への移行に伴う留意点 [UNIX]

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

プレポスト【問題】

デザインパターン第一章「生成《

PowerPoint プレゼンテーション

GEC-Java

第2回講義

ただし 無作為にスレッドを複数実行すると 結果不正やデッドロックが起きる可能性がある 複数のスレッド ( マルチスレッド ) を安全に実行する ( スレッドセーフにする ) ためには 同期処理を用いるこ とが必要になる 同期処理は 予約語 synchronized で行うことができる ここでは sy

科学的モデリング 2 回 継承 2 無断転載 & 無断配布を禁じます 第 2 回 : 科学的モデリング 継承 2 継承される特性( プロパティ ) 第 2 回の話題 継承は何を継承するのか? 今回のコラムの話題は 継承される特性 ( プロパティ ) についてです そもそもサブクラスはスーパークラスか

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

V8.1新規機能紹介記事

Another Activity オブジェクトは生成されてもいないのである これは 後述の onpause メソッ ドの説明からも明らかである 翻訳 : A の onpause から返ってこない限り B は create されない ため ここで長い処理は行ってはならない 実際にトレースをおこなってみ

目次 はじめに 4 概要 4 背景 4 対象 5 スケジュール 5 目標点 6 使用機材 6 第 1 章 C# 言語 7 C# 言語の歴史 7 基本構文 8 C 言語との違い 9 Java 言語との違い 10.Netフレームワーク 10 開発資料 10 第 2 章 Mono 11 Monoの歴史 1

Sort-of-List-Map(A)

POSIXスレッド

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

PowerPoint プレゼンテーション

intra-mart Accel Platform

PowerPoint プレゼンテーション

レコードとオブジェクト

Microsoft Word - Android_SQLite講座_画面800×1280

プログラミング入門1

プログラミング入門1

Microsoft Word 基_シラバス.doc

第 8 回の内容 クライアントサイド処理 JavaScript の基礎

Developer Camp

スライド 1

PowerPoint プレゼンテーション

WebOTXプロファイラを使用したメモリリーク調査方法

Prog2_12th

Javaと マルチスレッド

1

JavaプログラミングⅠ

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

受講を行うための前提知識 PC の基本操作ができること 座学 コーディング実習 受講講座の名称 9 日間 67:30 システムエンジニア向け IT 基礎 4/8/( 月 ) IT 技術者に共通する基本的な知識の習得を目標とします コンピュータ基礎では コンピュータの仕組みやコンピュータで扱う数値や単

メソッドのまとめ

Microsoft PowerPoint - kougi7.ppt

Full GC発生を抑止するメモリ管理技術

— intra-mart Accel Platform セットアップガイド (WebSphere編)   第7版  

表示の更新もそういた作業のひとつに当たる スレッドの使用アニメーション アニメーションやシミュレーションなどは画面の更新が一定のタイミングで行われていく この連続した画面の更新をスレッドを利用して行う しかし paint() メソッドを直接呼び出して表示を更新することはできない その理由


プログラミング基礎I(再)

スライド 1

Prog1_10th

4-1- 基 Java に関する知識 1 独立行政法人情報処理推進機構

2008 年度下期未踏 IT 人材発掘 育成事業採択案件評価書 1. 担当 PM 石川裕 PM ( 東京大学大学院情報理工学系研究科教授 ) 2. 採択者氏名 チーフクリエータ : 加藤淳 ( 東京大学理学部情報科学科学部学生 ) コクリエータ : なし 3. プロジェクト管理組織 株式会社メルコホ

ガイダンス

Microsoft PowerPoint - UML1_2009.ppt

Microsoft PowerPoint - chap10_OOP.ppt

Android Layout SDK プログラミング マニュアル

4-4- 基スクリプト言語に関する知識 コードの作成や修正が容易とされるスクリプト言語を学習し アプリケーション開発の手法を習得する 本カリキュラムでは まずスクリプト言語に位置づけされる Perl PHP Python JavaScript Ruby といった Ⅰ. 概要プログラミング言語の特徴に

PowerPoint プレゼンテーション

ガイダンス

11 ソフトウェア工学 Software Engineering デザインパターン DESIGN PATTERNS デザインパターンとは? デザインパターン 過去のソフトウェア設計者が生み出したオブジェクト指向設計に関して, ノウハウを蓄積し 名前をつけ 再利用しやすいようにカタログ化したもの 各デ

要求仕様管理テンプレート仕様書

Microsoft PowerPoint - 04_01_text_UML_03-Sequence-Com.ppt

Microsoft PowerPoint - C++_第1回.pptx

05-scheduling.ppt

4. UNO で広がる OpenOffice.org の世界 中本崇志 TAKASHI Nakamoto Copyright (C) 2006 名前 この文書は 以下の利用条件の元で公開されています クリエイティブコモンズ帰属 2.1 日本 http

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

(Microsoft Word - \225\361\215\220\217\221_\215K.doc)

第1章 ビジュアルプログラミング入門

ご利用のコンピュータを設定する方法 このラボの作業を行うには 事前設定された dcloud ラボを使用するか 自身のコンピュータをセットアップします 詳細については イベントの事前準備 [ 英語 ] とラボの設定 [ 英語 ] の両方のモジュールを参照してください Python を使用した Spar

ガイダンス

Javaプログラマー早期育成ドリル ~コードリーディング編~ 解答

プレポスト【問題】

JAVA入門

プログラミング入門1

Oracle Un お問合せ : Oracle Data Integrator 11g: データ統合設定と管理 期間 ( 標準日数 ):5 コースの概要 Oracle Data Integratorは すべてのデータ統合要件 ( 大量の高パフォーマンス バッチ ローブンの統合プロセスおよ

Microsoft PowerPoint - OOP.pptx

Delphi Generics.Collections

ガイダンス

組込みシステムにおける UMLモデルカタログの実践研究

Microsoft PowerPoint - prog03.ppt

Prog2_9th

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

Microsoft PowerPoint ppt

アジェンダ Renesas Synergy TM プラットフォーム構成 ThreadX とは ThreadX の状態遷移 ThreadX とμITRONの機能比較 まとめ ページ 2

PowerPoint プレゼンテーション

XNA Framework

Oracleセキュア・エンタープライズ・サーチ

PowerPoint プレゼンテーション

rcp-add-01:アーキテクチャ設計書

Prog2_10th

アスペクトの相互作用を解消するアスペクトの提案

JavaプログラミングⅠ

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 関数とメソッド 関数とメソッド Python には関数 (function) とメソッド (method) が有る モジュール内に def で定義されて居る物が関数 クラス内に def で定義されて居る物がメソッドに成る ( 正確にはクラスが

Prog2_10th

2004/11/23 オブジェクト指向プログラミング - モデル図とシーケンス図の表現方法 - オブジェクト指向プログラミング (OOP:ObjectOrientedPrograming) オブジェクト指向プログラミング言語 (OOPL) Java,C++,Delphi(Pascal),Visual

Microsoft PowerPoint - G-1_Flexでつくる初めてのRIA.ppt

クラスタ連携ガイド MSCS/MSFC 編

障害管理テンプレート仕様書

参考 - メインスレッドは JVM によって自動的に起動されるため 起動するコードを書く必要 はありません 今まで例題 演習で作成してきたプログラムは全てメインメソッドにて 動作している シングルスレッドです マルチスレッドマルチスレッドとは名前のとおり複数のスレッドと言う意味です マルチスレッドは

Java言語 第1回

Microsoft Word - A04 - Configuring Launch In Context_jp-ReviewedandCorrected a.doc

Transcription:

ファイナライザを理解する ~ ファイナライザに起因するトラブルを避けるために ~ 2013 年 11 月 25 日 橋口雅史 Java アプリケーションでファイナライザ (finalize() メソッド ) を使用したことがあるプログラマーは多いと思います しかし ファイナライザの仕組みや注意点について 理解したうえで使っているでしょうか? アプリケーション プログラムでファイナライザを使用する場合は ガーベジ コレクションの挙動などについて理解しておく必要があります そのため ガーベジ コレクションの仕組みと併せて ファイナライザについて解説します 1. はじめに Java には ファイナライザという仕組みが定義されています ファイナライザは 簡単にプログラムに組み込めます 一方で ファイナライザを間違って使うとトラブルを引き起こします 本書は ファイナライザの仕組みについて説明しています しかし ファイナライザの使用を推奨するものではありません ファイナライザは使い方が非常に難しいため 基本的にはファイナライザを使用しないでください ファイナライザの使用を検討する前に 目的を実現可能なほかの方法を検討してください どうしてもファイナライザを使う必要がある場合は 本書の内容を十分に理解した上で 必要最小限の範囲で使用してください 本書の対象読者本書は Java 言語 Java API などの仕様や Java に関する知識を持っている読者を対象にしています 本書では Java に関する基本的な用語などについて 詳しく説明しません 用語などに関する情報は それぞれの仕様書や一般書籍などを参照してください 2. ファイナライザにおけるよくある誤解 ファイナライザの仕組みについては 3 章以降で詳しく説明しますが ファイナライザに関してよく誤解さ れることを紹介します これらの誤解を解くことも 本書の目的のひとつです ファイナライザ実行のタイミングファイナライザを持つオブジェクトは それがゴミになった時点で すぐにファイナライザが実行されると誤解されることがあります 実際にはそのようなことはありません ファイナライザの実行タイミングをアプリケーションでは制御できません 1

ガーベジ コレクションとファイナライザの関係ファイナライザを持つオブジェクトは そのオブジェクトが到達不能になったあと ガーベジ コレクション (GC) 処理が 2 回実行されれば オブジェクトのファイナライザが必ず実行され そのメモリが回収されると誤解されることがあります 世代別 GC を実装している Java VM においては ファイナライザを持つオブジェクトが Old 領域に存在することがあります Old 領域に存在するオブジェクトは ファイナライザ到達可能になっても フル GC が実行されるまで ファイナライズ可能になりません そのため New 領域に対する GC が何度実行されても オブジェクトはファイナライズ可能になりません つまり ファイナライザは実行されません また GC 処理の最中 ファイナライザは処理されません そのため ファイナライズ待ちリストに大量のオブジェクトが存在する状態で GC が頻発した場合 いつまでもファイナライザが処理されないこともあり得ます 3. ガーベジ コレクションファイナライザは ガーベジ コレクション (GC) と密接な関係にあります そのため まず GC についての基本的な特徴を説明します 続いて 富士通のアプリケーションサーバーに採用している Java VM の GC 方式 ( 世代別 GC) について説明します ガーベジ コレクションの基本的な特徴 Java のメモリ管理では GC が重要な役割を果たします Java VM がオブジェクトを管理するメモリ領域 (Java ヒープ領域 ) がいっぱいになると Java VM は GC 処理を実行します GC 処理では 不要になったオブジェクトのメモリを開放し ほかのオブジェクトによってメモリを使用できるようにします Java VM は オブジェクトが必要かどうかを オブジェクトに対する参照が存在するかどうかで判断します つまり Java アプリケーションによって使用されているクラスのクラス変数や スタック上の変数から 参照をたどって到達できるオブジェクトは その時点で必要であると言えます 逆に 参照関係が途切れている場合 そこから先のオブジェクトには到達できないので 不要になったものと言えます ( 不要になったオブジェクトのことを ゴミ と言うこともあります ) クラス変数 到達できないオブジェクト ( 不要なオブジェクト ) 図 1 クラス変数から到達できないオブジェクトの例 2

世代別ガーベジ コレクション富士通のアプリケーションサーバーに採用している Java VM は Java ヒープを世代で管理して GC 処理の効率化を図っています Java ヒープは New 世代 Old 世代 および Permanent 世代のみっつの領域に分かれています Permanent 世代領域は ロードしたクラスの情報などが格納される領域です ファイナライザの説明とは関係しないため ここでは説明を省略します New 世代領域 Old 世代領域 一定回数の GC 処理を経験しても残存するオブジェクトは Old 世代領域に移される 図 2 世代別ガーベジ コレクション Java アプリケーションが生成を要求したオブジェクトのメモリは 通常 New 世代領域に割り当てられます New 世代領域がいっぱいになるまでオブジェクトが生成されると Java VM は GC 処理を実行します GC 処理が終了すると 参照が存在するオブジェクトだけが New 世代領域に残ります GC 処理が一定回数繰り返されたあとも New 世代領域に残っているオブジェクトは GC 処理によって Old 世代領域に移動されます Old 世代領域のメモリは Old 世代領域がいっぱいになるまでガーベジ コレクトされません この特徴は ファイナライザの挙動にも影響してきます 4. ファイナライザファイナライザとは finalize() メソッドのことです finalize() メソッドは Java 言語におけるすべてのクラスの継承元である java.lang.object クラスに定義されています すなわち すべてのクラスは finalize() メソッドを持ちます しかし java.lang.object クラスの finalize メソッドは何もしません finalize メソッドは 継承先のクラスでオーバーライドされたときに意味を持ちます ファイナライザは C++ 言語のデストラクタと同じものだと考えられることがあります しかし C++ 言語のデストラクタと Java 言語のファイナライザはまったく異なります C++ 言語のデストラクタは スタック上に作成されたオブジェクトが自動的に破棄される場合や メモリ上に作成されたオブジェクトが delete 演算子によって明示的に破棄される場合に呼び出されます つまり デストラクタを呼び出すタイミングをアプリケーションで制御可能です Java 言語のファイナライザは オブジェクトのライフサイクル すなわち GC 処理と密接に関わってい ます GC 処理は アプリケーションでは制御できません そのため ファイナライザを呼び出すタイミ 3

ングも アプリケーションでは制御できません ファイナライザについて理解するには オブジェクトのライフサイクルを理解する必要があります そのため ファイナライザが実行される仕組みを説明する前に Java VM がファイナライザを持たないオブジェクトをどのように制御するか説明します 次に Java VM がファイナライザを持つオブジェクトをどのように制御するか説明します ファイナライザを持たないオブジェクトのライフサイクル本書では ファイナライザを持たないオブジェクトのことを 便宜的に 通常のオブジェクト とします 通常のオブジェクトには オブジェクトへの参照が存在する状態 ( 到達可能 ) と オブジェクトへの参照が存在しない状態 ( 到達不能 ) が存在します 表 1 通常のオブジェクトの状態一覧 オブジェクトの状態到達可能 (reachable) 到達不能 (unreachable) Java アプリケーションによってオブジェクトの生成が要求されてから そのメモリが回収されるまでの 状態は 次のように遷移します 状態遷移 オブジェクト生成要求 メモリ割り当て済み オブジェクトへの参照を設定 到達可能 オブジェクトへの参照がすべてなくなる 到達不能 ガーベジ コレクション処理 メモリ回収済み 図 3 通常のオブジェクトの状態遷移 オブジェクトが到達不能な状態に遷移すると それ以降の GC 処理によってそのオブジェクトのメモリ は回収されます 回収されたメモリは ほかのオブジェクトを生成するときのメモリとして再利用されま 4

す ファイナライザを持つオブジェクトの管理方法ファイナライザを持つオブジェクトの管理方法は 通常のオブジェクトと異なります 一般的な Java VM では ファイナライザを持つオブジェクトを特別なリストで管理します このリストを便宜的に ファイナライザ管理リスト と呼びます Java VM は ファイナライザを持つオブジェクトのメモリを割り当てると同時に ファイナライザ管理リストでも管理します ファイナライザ管理リストは Java アプリケーションからは操作できません リストの目的は ファイ ナライザを呼び出すまで Java ヒープ内にオブジェクトを留めておくことです ファイナライザ管理リスト 図 4 ファイナライザ管理リストの概念図 オブジェクトに到達可能な参照が ファイナライザ管理リストだけになると Java VM は そのオブジェクトのメモリを回収するまえにファイナライザを実行します ファイナライザを実行するため Java VM は オブジェクトをファイナライザ管理リストから別のリストにつなぎかえます このリストのことを便宜的に ファイナライズ待ちリスト と呼びます ファイナライザ管理リスト ファイナライズ待ちリスト 図 5 ファイナライザ管理リストからファイナライズ待ちリストへの移動 ファイナライズ待ちリストにつながれたオブジェクトは Java VM によってファイナライザが実行され ます ファイナライザが実行されると ファイナライズ待ちリストからの参照もなくなります 5

ファイナライザ管理リスト ファイナライズ待ちリスト ファイナライザ実行済み (GC の回収対象 ) 図 6 ファイナライザ実行後のリストの状態 このような状態になると オブジェクトは GC の回収対象になります ファイナライザを持つオブジェクトのライフサイクル ファイナライザを持つオブジェクトには 通常のオブジェクトに加えて ファイナライザ到達可能 と いう状態が存在します 表 2 ファイナライザを持つオブジェクトの状態一覧 オブジェクトの状態到達可能 (reachable) ファイナライザ到達可能 (finalizer reachable) 到達不能 (unreachable) また ファイナライズの状態という属性も考慮する必要があります 表 3 ファイナライズの状態一覧 ファイナライズの状態未ファイナライズ (unfinalized) ファイナライズ可能 (finalizable) ファイナライズ済 (finalized) Java アプリケーションによってオブジェクトの生成が要求されてから そのメモリが回収されるまでの 状態は 次のように遷移します 6

状態遷移 オブジェクト生成要求 メモリ割り当て済み 未ファイナライズ オブジェクトへの参照を設定 到達可能 未ファイナライズ オブジェクトへの参照がファイナライザ 管理リストだけになる ファイナライザ到達可能 未ファイナライズガーベジ コレクション処理ファイナライズ可能ファイナライザ実行ファイナライズ済 オブジェクトへの参照がなくなる到達不能ファイナライズ済ガーベジ コレクション処理メモリ回収済み 図 7 ファイナライザを持つオブジェクトの状態遷移 オブジェクトへの参照がファイナライザ管理リストだけになると オブジェクトの状態は ファイナライザ到達可能 に遷移します ファイナライザ到達可能 の状態に遷移したオブジェクトは それ以降に実行される GC 処理によって ファイナライズ待ちリストにつながります それにより ファイナライズの属性は ファイナライズ可能 に変化します ファイナライズ待ちリストに繋がったオブジェクトは Java VM によってファイナライザが実行されま す ファイナライザが呼び出されると オブジェクトのファイナライズの属性は ファイナライズ済 に変 化します そして ファイナライズ待ちリストからの参照がなくなります つまり オブジェクトに対す 7

る参照がなくなります オブジェクトへの参照がなくなると 状態は 到達不能 に遷移します そして それ以降に実行される GC 処理によって オブジェクトのメモリが回収されます このように ファイナライザを持つオブジェクトのメモリが回収されるまでには 通常のオブジェクト よりも多くの状態遷移が必要です また アプリケーションで制御することができません 5. ファイナライザに関する注意事項 ファイナライザに関する注意事項について説明します ファイナライザの実行順序は不定ファイナライザは アプリケーションが実行されるスレッドとは別のスレッドで処理されます また ファイナライザが実行される順序は不定です アプリケーションではその順序を制御できません その特徴により 特に同期処理で問題が発生する可能性があります 例えば ファイナライザ以外の処理とファイナライザのあいだで同期を取ろうとすると プログラマーが意図しない順序でファイナライザが実行された結果 デッドロックに陥ることがあります ファイナライザとファイナライザ以外の処理のあいだでは 同期処理を行わないでください ファイナライザ以外の処理 ファイナライザ? どのファイナライザが いつ実行されるか分からない? 通常の処理間では問題なく同期できても ファイナライザとはうまく同期できない 図 8 ファイナライザの同期処理に関する問題 ファイナライザをリソース管理に使ってはいけないメモリなどのリソースをファイナライザで解放するようなプログラムは リソースのリークを招く恐れがあります ファイナライザの実行タイミングはアプリケーションで制御できません また Java VM がファイナライザをいつ実行するのかも分かりません 場合によっては ファイナライザが実行されるまでに非常に長い時間がかかることがあります そのような場合 リソースの解放をファイナライザに頼っていると いつまでもリソースが解放されないことになります オブジェクトのメモリがガーベジ コレクタによって回収されたことを契機としてリソース解放などの処理を行いたい場合は java.lang.ref パッケージを使用してください 8

リソースの解放が必要なクラスには 解放用のメソッドを用意してください そして インスタンスの使用が終わったらそのメソッドを呼び出してください ファイナライザは そのメソッド呼び出しを忘れてしまったときでもリソースを解放する後始末の役目としてだけ用意してください java.io パッケージに含まれるクラスなどは そのような実装になっています それらのクラスのインスタンスに対しては そのインスタンスの使用が終わったら原則として close() メソッドを呼び出してリソースを解放する必要があります 万が一 close() メソッドが呼び出されなかったときのために ファイナライザでもリソースを解放します System.runFinalization() でファイナライザを確実に実行できるわけではない Java には java.lang.system.runfinalization() というメソッドがあります そのメソッドを呼び出せば ファイナライザを実行できると思われることがありますが そのようなことはありません runfinalization() メソッドは 先に説明した ファイナライズ待ちリスト に繋がっているオブジェクトのファイナライザを呼び出すものです しかし ファイナライズ待ちリストに繋がっていないオブジェクトに関しては何の効果もありません また オブジェクトがファイナライズ待ちリストに繋がるタイミングは Java VM の処理に依存するため runfinalization() メソッドをいくら実行してもファイナライザが実行されないことがあります ファイナライザの処理中に発生した例外は無視される Java 言語仕様で定義されているように ファイナライザの処理中に発生した例外は無視されます また その時点でファイナライザの処理は終了します 例外は Java 実行環境やアプリケーションの異常によって発生することがありますが ファイナライザは発生した例外を無視します そのため なんらかの異常を残したまま アプリケーションが動き続ける可能性があります また 例外の発生によりファイナライザの処理が中断されるため 期待した処理が完了せず 思わぬ問題を引き起こすことがあります ファイナライザに記述する処理は 例外が発生しないものか 例外が発生しても無視してよいものに限 ってください 親クラスがファイナライザを使っていることがあるプログラムではファイナライザを使っていないのに ファイナライザが原因でトラブルが発生することがあります それは プログラムで定義したクラスの継承元でファイナライザを使用している場合です そのようなトラブルを未然に防ぐのは難しいですが 有効な方法のひとつは クラスの設計時に不要な継承関係を作らないことです アプリケーションの設計時に Java のコアライブラリなどに含まれるクラスを継承する必要性を十分に 検討してください すなわち オブジェクト指向における is-a 関係ではなく has-a 関係による目的 9

の実現を検討してください また インタフェースの実装をクラスの継承で代用しないでください ( プログラミングが簡単になるという理由だけでクラスの継承を選択しないでください ) インタフェースの実装が必要な場合は まずその実現を検討してください GC が頻発するとファイナライザの処理が進まないファイナライザは GC の最中は処理されません GC が頻発するような状況になると ファイナライザの処理が一向に進まなくなります ファイナライザによるリソースの解放を期待するようなプログラムでは GC によるファイナライザ処理の遅延 ファイナライザ処理の遅延による Java ヒープ領域の圧迫 GC の発生 GC によるファイナライザ処理の遅延 という悪循環に陥ることがあります 6. 参考文献 The Java Language Specification Java SE 7 Edition http://docs.oracle.com/javase/specs/jls/se7/html/index.html 10