(Javaで)作成しているプロジェクトで、教授が200mを超えて使用することは許可されていないと言っています。スタックメモリを-Xmx50mで50mに制限します(絶対に確実ですが)。 、それはまだ300メートルを使用しています
私は Eclipse Memory Analyzer を実行してみましたが、26mしか報告されません
これはすべてスタック上のメモリですか?、約300のメソッド呼び出しの深さを超えることはないと確信しています(そうです、これは再帰的なDFS検索です)。つまり、すべてのスタックフレームがほぼ使い尽くされていることになります。信じがたいメガバイト。
プログラムはシングルスレッドです。メモリ使用量を削減できる可能性のある他の場所を誰かが知っていますか?また、スタックが使用しているメモリの量を確認/制限するにはどうすればよいですか?
更新:以下のJVMオプションを使用していますが、効果はありません(上によると、約300mです):-Xss104k -Xms40m -Xmx40m -XX:MaxPermSize=1k
別の更新:実際、私がそれを少し長く実行すると(これらすべてのオプションを使用)、約半分の時間で4または5秒後に突然150mに落ちます(残りの半分は落ちません)。これが本当に奇妙なのは、私のプログラムには確率論的ではない(そして私が言ったようにシングルスレッドである)ため、実行ごとに異なる動作をする必要がある理由はありません。
私が使用しているJVMと何か関係があるのでしょうか?
Java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~10.04)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Java -hによると、デフォルトのJVMは-serverです。-cacaoを追加してみましたが、他のすべてのオプションを使用して)わずか59mです。これで私の問題は解決すると思います。これが必要だった理由を説明してください?また、知っておくべき欠点はありますか?
もう1つの更新:カカオはサーバーに比べて本当に遅いです。これはひどいオプションです
上のコマンドは、Javaアプリケーションによって使用されるメモリの総量を反映しています。これには、特に次のものが含まれます。
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]
ここで、最大ヒープメモリは-Xmx、最小ヒープメモリは-Xms、スタックメモリは-Xssおよび-XX maxPermSizeです。
次の例は、この状況を示しています。 Tomcatを次の起動パラメーターで起動しました。
-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m
-Xmx
では、ヒープサイズを構成しています。スタックサイズを設定するには、-Xss
パラメータを使用します。これらの2つのパラメーターの合計は、おおよその値になります。
-Xmx150m -Xss50m
例えば。
さらに、制御する-XX:MaxPermSize
パラメータもあります。 -client
のこのパラメーターのデフォルト値は32MBで、-server
のデフォルト値は64MBです。構成に応じて、それも計算します。 PermGenスペースは次のとおりです。
永続的な生成は、クラスオブジェクトやメソッドオブジェクトなどのVM自体を反映するために使用されます。
したがって、基本的にはクラス定義や内部ストリングなど、JVMの内部データを格納します。
最後に、私はあなたが制御できない1つの部分があることを言わなければなりません、それはネイティブで使用されるメモリですJavaプロセス。Javaはプログラムです、ちょうど他と同様に、メモリも使用しますタスクマネージャでメモリ使用量を監視している場合は、プログラムのメモリ消費量とともにこのメモリも表示されます。
「総メモリ使用量」(LinuxランドのRSS)には、JDKヒープ(およびその他のJDK領域)と、割り当てられた「ネイティブメモリ」が含まれることに注意することが重要です。
たとえば、これらの人々は、GC間で(ネイティブメモリに関連付けられている)jaxbcontextをあまりにも多く割り当てると、余分なRAMを大量に使用する可能性があることを発見しました。もう1つの一般的なものは、close(またはGZipStreamなど)を呼び出さない場合のZipInflaterです。
http://sleeplessinslc.blogspot.com/2014/08/jvm-native-memory-leak.html
彼の最後の回避策/修正は、GCを「より頻繁に」(GC1ガベージコレクターを使用するか、smaller[皮肉なことに] -Xmx設定を指定して)、またはJaxBContextオブジェクトをキャッシュする(オブジェクトにはcloseメソッドがないため、リークを制御できないため)。
また、jstackを調べるだけでメモリの原因を見つけることができる場合もあります。 http://javaeesupportpatterns.blogspot.com/2011/09/jaxbcontext-performance-problem-case.html
また、たとえばGZipStreamsを誤って閉じるのを「ミス」する可能性もあります http://kohsuke.org/2011/11/03/quiz-time-memory-leak-in-Java
JVisualVMを使用してみましたか?
http://docs.Oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html
これを追跡するのに役立つことがよくあります。各種類のメモリがどの程度使用されているかが表示され、ドリルダウンして何を見つけることもできます。