2011-01-11 13 views
9

私は最近、私が作業している既存のコードベースで次のスニペットを実行し、そこに表示されているコメントを追加しました。私は、この特定のコードをきれいにするために書き直すことができますが、私の分析が正しいかどうか疑問に思っています。多くの同一の匿名クラスを宣言すると、Javaのメモリが浪費されますか?

javaは新しいクラス宣言を作成し、このメソッドの呼び出しごとにperm gen空間に格納しますか、または既存の宣言を再利用することはわかりますか?

protected List<Object> extractParams(HibernateObjectColumn column, String stringVal) { 
    // FIXME: could be creating a *lot* of anonymous classes which wastes perm-gen space right? 
    return new ArrayList<Object>() { 
     { 
      add(""); 
     } 
    }; 
} 
+0

しかし、静的なネストされたクラスではなく内部クラスを使用すると、外側の$ thisポインタのために少しのメモリが無駄になることがあります。それはヒープメモリだろう。 – Thilo

+0

コードが重複していると、コードが煩雑になり、管理が難しくなります。 –

答えて

15

クラスはコンパイル時に1回のみコンパイルされます。コンパイラは(MyOuterClass$1のような名前の)クラスを抽出して使用します。もちろん、複数のインスタンスが作成されますが、それらはすべて同じクラスになります。 .javaファイルをコンパイルすると、生成された.classファイルを見ると、内部の匿名クラスのファイルが存在することがわかります。

5

つのクラスの多くのインスタンスを作成しません、。テストするには、あなたの匿名クラス内でこれを置く:

@Override 
public String toString() { 
    return getClass().getName(); 
} 

そして、匿名クラスの様々なインスタンス上toString()を呼び出します。彼らは皆同じ​​クラス名を返します。

3

他の回答は正しいです。しかし

:そのパターンは、あなたのコード内で何度も繰り返されている場合

  • は、その後、あなたは内部クラスの同数となってしまいます。パターンを数百回/数千回使用すると、コードフットプリント/ permgenの使用量が増加したは、となる可能性があります。より簡単に

    あなたが複数の値を持つリストを移入する必要がある場合については
    protected List<Object> extractParams(HibernateObjectColumn column, 
                String stringVal) { 
        return Collections.singletonList(""); 
    } 
    
  • として表現することができあなたは、この特定の例ではやっている

  • は、静的なヘルパーメソッドを含むソリューションは、おそらく簡単です。

+0

ああ、感謝します、ありがとう。 Collections.singletonList( "")は不変のリストを提供し、クライアントコードが結果を変更する可能性があるので、この特定のケースではおそらくArrays.asList( "")と置き換えます。 – depsypher

+0

はい - 'Arrays.asList(...)'は良い解決策です。 –

+0

@depsypherしかし、 'Arrays.asList'の結果はまだサイズ変更できません。 'Collections.singletonList'が' list.set(0、...) 'を使っていないことは、(この例では)唯一可能です。また、不変のリストを返すときには、APIがより洗練されています。呼び出し元は、リストを変更したいときは本当にリストをクローンする必要があります。浅いリストのコピーは高価ではありません。 –

0

はJavaで多くの同一匿名クラスの廃棄物のメモリを宣言していますか?

もちろん、あなたが投稿したコードではそうしていません。

+0

彼は確かに1つの匿名クラスを宣言しています。私は、彼が多くの場所でそのコードを持っていることを意味すると思います。 – tster

+0

@tster正確に。彼は1つの嫌なクラスを宣言している。 「たくさん」ではありません。含める必要はありません。彼は明示的に「Javaは新しいクラス宣言を作成し、このメソッドの呼び出しのたびにperm gen空間に格納しますか?」と尋ねています。それはできません。 – EJP

関連する問題