- PR -

HashMapインスタンス変数のガベージコレクション

1
投稿者投稿内容
プレミアム
会議室デビュー日: 2007/08/15
投稿数: 9
投稿日時: 2008-05-13 21:18
標記の件について、よく理解できていないので教えてください。

以下のようなクラスを作成しようと考えています。

コード:
import java.util.HashMap;

public class HashMapHolder {
	private HashMap hash = null;

	public HashMapHolder(){
		hash = new HashMap();
		hash.put("key", "value");
	}

	public String getVal(String key){
		if(false == hash.containsKey(key)) return null;
		return (String)hash.get(key);
	}
}



このクラス「HashMapHolder」インスタンスへの参照がなくなった場合、
クラス内のインスタンス変数である「hash」はガベージコレクション
の対象になるのでしょうか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-13 21:37
引用:

プレミアムさんの書き込み (2008-05-13 21:18) より:

このクラス「HashMapHolder」インスタンスへの参照がなくなった場合、
クラス内のインスタンス変数である「hash」はガベージコレクション
の対象になるのでしょうか?



なります。
したがって HashMapHolder クラスは、その存在意義がないです。

HashMap を使ってどういうことをされたいのかを書かれたほうが良いかもしれません。
プレミアム
会議室デビュー日: 2007/08/15
投稿数: 9
投稿日時: 2008-05-13 23:41
unibonさん返答ありがとうございます!

下記URLにあるような記述をよく見かけたので、
HashMapインスタンスがガベージコレクトされない状況・条件とは
具体的にどんなものなのかを知りたいのです。


引用:

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=35323&forum=12&10
・Javaのプログラムでメモリリークを起こしやすいのは、java.util.HashMap のようなMapコレクションクラスです。
Mapには、自由にデータを出し入れできるのですが、不要になったデータを削除することを忘れてしまい、リークオブジェクトが溜まってしまいます。(Vol.47 号)



引用:

http://defaultsettings.hp.infoseek.co.jp/contents/hack/pg/Java.html
しかし、java.util.HashMap などをインポートして生成して管理しているインスタンスは、ガベージコレクションされない。



---
unibonさんのおっしゃるとおり
前述の「HashMapHolder」の存在意義は確かにないですがー、
 1、コンストラクタの引数になにか文字列などを渡して→パースしてHashMapにセット
 2、インデクサ的なpublicメソッドでその内容を参照する
みたいなコードを書こうと思ってました。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2008-05-14 10:36
マーク・アンド・スイープについて調べてみてください。
これはガーベッジコレクションのアルゴリズムの手法なのですが、根っこから繋がっているオブジェクトにマークを一通りつけてから、マークの付いていないものを削除する手法ですね。
根っこの部分というのはstatic変数とかだと思ってください。
参照の木構造がイメージできるでしょうか?
この参照の木構造から孤立したものがガーベッジコレクションで回収されるわけです。

なので、特に気をつけるべきは、static変数や、ライフサイクルの長いオブジェクトに保持される変数です。
後者はたとえばJavaEEのServletのようなオブジェクトが該当します。
プレミアム
会議室デビュー日: 2007/08/15
投稿数: 9
投稿日時: 2008-05-14 14:01
nagiseさん、アドバイスをありがとうございます。

マーク・アンド・スイープなど、GCに関わる部分を勉強してみます。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-14 15:15
引用:

プレミアムさんの書き込み (2008-05-13 23:41) より:
下記URLにあるような記述をよく見かけたので、
HashMapインスタンスがガベージコレクトされない状況・条件とは
具体的にどんなものなのかを知りたいのです。


リンク先は読んでいませんが、別に HashMap というものが特別なものではないです。

HashMap の代わりにただ1個の Object を入れる入れ物だとしても同じことです。
たとえばつぎのようなものを使うことと HashMap を使うことに、ガーベッジコレクション云々においては違いはありません。
コード:
public class HogehogeHolder {
	private Object obj = null;

	public HogehogeHolder(){
		obj = new Object();
	}

	public Object getVal(){
		return obj;
	}
}


と同じことです。

HashMap を使うときに注意しないといけない、というのは、たんに便利な押入れがあって、そこにどんどん詰め込んでいったら、いつのまにか詰め込んだことを忘れてしまっているけど、詰め込んだ人は押入れの存在は知っているので、押入れは勝手にガーベッジコレクションされない、したがって、押入れの中に詰め込んだものもずっと勝手には消えないというだけのことでしょう。普通の Object/String や配列やせいぜい List 位だと、その存在は結構気にとどめますが、HashMap などになると key で検索しないといけないので、どんな key にどんな value を入れたかをちゃんと覚えていないと、バグで残ったままになる(メモリーリークになる)、というだけのことでしょう。

引用:

プレミアムさんの書き込み (2008-05-13 23:41) より:
unibonさんのおっしゃるとおり
前述の「HashMapHolder」の存在意義は確かにないですがー、
 1、コンストラクタの引数になにか文字列などを渡して→パースしてHashMapにセット
 2、インデクサ的なpublicメソッドでその内容を参照する
みたいなコードを書こうと思ってました。


パース後にその HashMap の内容が不要になるのならば、clear したり HashMap を指す変数に null を入れたりするだけで良いです。とはいえ、これをプログラマーのバグで忘れやすい、というだけのことです。
ガーベッジコレクションを気にする必要はまったくありません。
1

スキルアップ/キャリアアップ(JOB@IT)