2017-08-30 3 views
1

thisthisのような静的な記事やチュートリアルでは、静的変数はクラスローディング時にクラス領域内で1回だけメモリを取得するため、静的使用はメモリ管理に適していると言われています。メモリ管理にStaticを使用しているかどうかを確認しますか?

しかし私の友人は静的メソッドがスタックに保持されていると言いました。ヒープの管理はスタックよりも簡単で、ガベージコレクタはヒープ上でしか動作せず、アプリケーションが実行されている間はスタックがきれいにならないので、できるだけ少ない

注:

「私はスタックメモリについてstackoverflowの中に同じ質問を読みましたが、それらは「PermGenスペース」や他の単語を使用して、いくつかの方法が複雑で専門的であるため、私は、それの多くを取得していない私はドン知っている。

友人の前進が正しいかどうか誰かに説明してもらいたいですか?

私はそれが依存していることを知っています。私は静的メソッドと静的メソッドの両方でデザインすることができます。メモリ管理はどちらが良い方法だろうか?

+3

どちらも間違っています。それがあなたのデザインに適している場合はそれを使用し、それ以外の場合は使用しないでください。メモリ管理があなたの主な関心事であるべきではありません。 – shmosel

+0

私はそれが依存すると思う。 – Willmore

+0

スタティックメンバーはスタックしません。 PermGenでそれが重要だと思います。 [link](http://www.journaldev。 – MehmanBashirov

答えて

4

答えは次のとおりです。この質問は、時間とエネルギーを間違った場所で過ごすことを意味します。

優れたパフォーマンスを発揮するJavaアプリケーションを実現するための重要な役割:お客様の要件を真正面から実装するエレガントなOOP設計を思いついてください。

ジャストインタイムコンパイラの動作によって、の実行時間で「Javaパフォーマンスの魔法」がほぼ完全に発生することを理解する必要があります。そして、JITはJavaで「ベストプラクティス」と見なされる一般的に使用されるパターンに最も適しています。

「特別な」コードでは、「場所を選ばず静的に使用できます」というような「特別な」アイデアが出てくると、最終的にパフォーマンスが悪化する可能性があります。 。

So:それぞれJITを信頼してください。そして、これらのツールが "最適な"方法で動作することを確認してください。他の誰もがやっていること!

早すぎる最適化の考えは、あなたのOOPデザインを破壊しないでください。 intensive低レベルの最適化が必要な貴重なカテゴリにアプリケーションが含まれていても、GCとJITの動作を勉強するのはです。

つまり、このような問題はリアルの問題ではありません。意味:もちろん

  • あなたは完全に愚かなミスを避けるしかし
  • を使用すると、そうでない場合は、メモリやパフォーマンスのトピックに関するない心配を行うあなたが手元に本当問題を(持っているない限り、例えば、あまりにも必要とするアプリケーションで多くの記憶や顧客があなたに不平を言う)。

そして - あなたは「本物」の問題に遭遇したときに:あなたはプロファイル問題の根本的な原因を理解するために、アプリケーションに持っています。繰り返しますが、そのような時期尚早な(無学の)最適化の考え方が、あなたのデザインに悪影響を与えることは許されません。

そして、私が十分にはっきりしていなかったことを暗示しているように、実際のメモリ問題があるときは、は絶対にには「パーマ生成」のような用語を理解する必要があります。そのため、の詳細でGCがどのように動作するのかを理解する必要があります。真剣に:という静的なキーワードが「メモリ効率の良い」アプリケーションを作成する上で重要な役割を果たしていないと言っている人々をここで信じてください。

+1

メモリ管理は私の主な関心事ではありませんが、私はどちらを考えていたのですか? 1つは、私が選択する権利を持っているときに好む、静的メソッドを使用しないか、問題ないし、メモリを使用するのが良いということです。 – user5621266

+0

私はあなたがまだ私のポイントを得ていないと思う。今追加した段落を参照してください。 – GhostCat

+0

私の経験では、顧客が不平を言ってくると、メモリ管理に関連した悪い設計上の決定を修正するのは時期尚早です。そのような場合に通常起こるのは、不適切な設計を回避するために特別なkludgesが作られるということです。しかし、メモリ管理がアプリケーションの重要な要素であると思うなら、JVMがこの点でどのように機能するかについて、本当に詳細かつ完全に理解する必要があります。あいまいなルールに頼ることはあまり助けにならないでしょう。 –

2

静的変数のメモリ割り当ては、プログラムの最初の実行時に1回のみ発生します。 これをクラスで使用している場合は、そのクラスのすべてのオブジェクトが共有するインスタンスが1つだけ作成されます。ですから、メモリ消費量は少なくなります。静的メソッドと変数はPERMGEN空間に格納されます。しかし、今ではMETASPACEという新しいメモリ空間が導入されました。これはクラスメソッドとクラスプールと定数プールのフィールドが保存される場所です。 METASPACEの詳細については、「https://dzone.com/articles/java-8-permgen-metaspace

+0

スタックメモリの役割は何ですか? – user5621266

3

です。短い答えはあなたが間違っているということですか? classオブジェクト自体(つまり、java.lang.Class<T>のインスタンスはスタックに割り当てられません) Javaはクラスをロードし、ロードされた関数の最後にクラスをアンロードしないので、スタックには移動できません。

警告:この回答の残りの部分では、JVM実装の詳細とガベージコレクションのメモリ管理について説明しています。ほとんどのアプリケーションでは、これらの事実を考慮する必要はありません。可能な限りプログラムの正確さに頼るのではなく、リリースごとに変更してください。

多くの最新のJVMは世代別ガベージコレクタを使用しています。システムによってロードされたクラスはアンロードされませんが、Java 8でOracleによって置き換えられるPermanent Generation(PermGent)と呼ばれる領域にそれらを置くことができ、質問が参照するクラスメタデータを保持するMetaSpaceで置き換えられます。しかし、これらはOracle JVMの実装の詳細であり、Java仕様の一部ではないことを認識してください。

他の可能性のある混乱は、これがすべてクラスによって直接必要とされる空間に適用され、静的参照ではなく、それらの参照が参照するものではないことです。例では

class Sample { 
    private static BigThing biggie=new BigThing(10000); 
} 

biggie参照が何か他のもののように、ヒープ上に作成されるオブジェクト。実際にはここではfinalとは宣言されておらず、再割り当てできるので、実行中の任意の時点で作成されたオブジェクトを参照することができます。 (私の知る限りでは)変わらずにあるJVMのこの領域が変化し、年間のチューニングが、することが課題となっているのでご注意ください

https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace

:ここ

は、トピックに関する比較的最近の記事ですJava 9

関連する問題