人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Javaについてです。
以下のソース1、2とでは、メモリの消費に差が出ますか?
「MAX==20000」程の処理を行う予定があります。

ソース1
for (int i = 0; i < MAX; i++) {
Hoge hoge = new Hoge();//ループ内で毎回変数を宣言
(処理)
}

ソース2
Hoge hoge = null;//ループ外で変数を一度だけ宣言
for (int i = 0; i < MAX; i++) {
hoge = new Hoge();
(処理)
}

また、ループ内の最後の行で、hoge = null;を書くのと書かないとではどうでしょうか。
フィールドと違い、ローカル変数にnullを入れるのはメモリ消費的には無意味と聞いたことがあるのですが本当でしょうか。

●質問者: kurokumi
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:hoge Java MAX どうでしょう ソース
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● newta
●20ポイント

あまり変わらないと思います。

ソース2のとき

hoge = new Hoge();

とした瞬間、以前参照していたインスタンス参照がはずれGC対象になると思うので、

nullを明示的にセットしてもしなくても変わらないと思います。

フィールドでもGC対象になるかならないかが重要であって、

明示的にnullセットするとかはあんまり関係ないと思います。


2 ● あひる
●20ポイント

メモリ効率に関してはどちらもまったく一緒ですね。どちらの場合もすぐにガベージコレクションの対象となります。

また、最後にNULLを入れてやる件ですが、ガベージコレクションの対象になるのが僅かに早くなるだけで、実質的には何の意味もないと思います。明らかに不要な参照が残ってしまうような場合でないかぎり、無用なコードです。


3 ● 池田仮名
●20ポイント

オブジェクトがガーベージコレクション対象になるのは参照が外れた時であるのでnullの代入とともに「変数がスコープ外にあること」を意識されると良いと思います。

質問内容について強いて言えばソース2の方が最後の一回についての参照がもう一段階上の括弧閉じの部分まで残り続ける分は損だと考えられます。

とはいえ参照外になったところで即座に解放処理が行われるわけではないため注意が必要です。

JavaVMのメモリ構造とガーベージコレクションについては以下のURLが参考になると思われます。

http://www.atmarkit.co.jp/fjava/rensai3/devedge03/devedge03_1.ht...

◎質問者からの返答

ありがとうございます。

皆さんのご意見をまとめると、ほとんど変わらないということのようなんですが。

下記のような解説を見つけたのですが、どうなんでしょうか。

http://www.sgnet.co.jp/java/chapter0502.html


4 ● 池田仮名
●40ポイント ベストアンサー

コメントへのご回答ですが、URLの例はインスタンスの内部変数を使う前に初期化することで生成しないという話であり、

特定条件において「生成コスト*使用回数 + 解放コスト > 初期化コスト」で有る場合に有用な方法です。

これはご質問内ののHoge()の変数がたとえばint x, int yだけだった場合に使い回しをして、

生成処理をしないで初期化というような意味になります。


Hoge hoge = new Hoge();

for (int i = 0; i < MAX; i++) {

/* hogeのインスタンス変数を初期化 */

hoge.init(xx, yy);

(処理)

}


ただし、hogeを他から参照変数として使用している場合などは当然、参照先が変更されますし、

初期化処理の仕様誤解やクラス定義を変更したときの初期化処理の変更忘れといったバグの温床になるので注意が必要です。

以上はhogeの内部変数を変更する場合の副作用であるのでHogeの中身が一切変わらないのであれば

forの外どころかプログラム全体で1回だけ生成して一切作り直さない方がよいでしょう。

その場合はデザインパターンでいうところのシングルトンパターンなどが参考になります。

余談ですが現在のJDKであると文字列型の直接演算は最適化処理でStringBuillderという文字列生成クラスを使う

処理に変換されるため、StringBufferを使うやり方はむしろ遅くなる場合が多いと言われています。

以上分かりづらかったかもしれませんがご参考までに


5 ● nake
●20ポイント

ソース2のほうがメモリー消費に関してはよさそうに思われます。

http://www.sgnet.co.jp/java/chapter0502.html

Stringオブジェクトは特別なので、普通のオブジェクトと比較してもあまり意味がないかと。

◎質問者からの返答

例に挙げたURLはStringオブジェクトではなく、StringBufferですよね。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ