序文
このトピックでは、書き込みがはい、本当にあるので、子供の靴の隣のブロガーは、最近と呼ばれる記事「ThreadLocalのメモリリーク、」記事を書いたので、私は、再び彼女を行った理由は、私は、リンクではないよ、すでに一般的です。。(百万本の言葉は省略)
私も無意味に頼まれた、仕上げに焦点を当てました。人道懸念のうち、ブロガーは非常に恥知らずを書きます。
テキスト
定義
大勢の人たちが、メモリオーバーフローやメモリリークの違いを理解していないので、まず、私たちはまず、定義について話す必要があります。
メモリ・オーバーフロー(OutOfMemoryを):あなただけの10ドルを持って、私はあなたが百であることがわかりました。ごめんなさい、ああ、私はそんなにお金を持っていません。(给不起)
メモリリーク(MemoryLeakは):あなたは10ドルを持って、私は1つのためにあなたを探しています。しかし、恥知らずなブロガーは、あなたにそれをすべてを与えることはありません。(没退还)
関係:複数のメモリリークがメモリオーバーフローを引き起こす可能性があります。(ブロガーがより多くのお金を数回あなたを見つけるために恥知らず、あなたはお金がない、真実です。)
害
[OK]を、私は、プロジェクト内の例のJavaプログラムより多くのカードを発生していません。
メモリリークが頻繁になりますのでFull GC
、およびFull GC
プログラムが停止し、最終的にクラッシュする原因となります。だから、あなたはあなたのプログラムより多くのカード、複数のカード、あなたは軽蔑されるプロダクトマネージャーを感じるだろう。ちなみに、私たちはチューニングJVM理由は、減少させることにあるFull GC
外観を。
私はプロジェクトがちょうどライン上で良いされているとき、私は一度会っていた覚えています。時間の蓄積の結果として、それが報告されましたOutOfMemoryError: PermGen space
。
それはこれに来るときはPermGen space
、電源の突然のバースト先史時代、本体ボーから噴き出す、メソッド領域を教えてください、それを越えて行く、結局のところ、これは「あきらめエントリからJVM。」について話されていません
メソッドエリア:Java仮想マシン仕様から、用スレッドシェアのそれぞれの実行時のメモリ領域。これは、格納、各クラスのコンフィギュレーション情報、例えば、実行時定数プール(Runtime Constant Pool
)、バイトコード・データ・コンテンツ・フィールドとメソッド、およびコンストラクタ通常の方法を。
上記内部異なる仮想マシンに実装ノルムが、同じではないが、最も一般的である(PermGen空間)の永久的な生成と素子間隔(メタスペース)。
jdk1.8前:実装面積が永久的な世代と呼ばれます。そのため非常に長い時間前に、ほとんどありませんJavaクラスの静的めったに、とはアンロードされ、回収ので、彼らが与えている恒久的な世代ブレアは言ったが。だから、あなたがプロジェクト内にある場合、ヒープおよび永続的な世代が、回収率は、単にこれは、メモリリークが発生することはほぼ確実であることはいうまでもない、ペースを維持することはできません減少していない、成長してきました。
jdk1.8後:エリアの実装は、元のスペースと呼ばれます。曲は非常に困難であることのJavaの永続的な世代。メタデータの生成はそれぞれに永久的であってもよいFull GC
出現移動します。そして、永久歪みを代入すると、空間の大きさを決定することは困難です。これにより、Javaクラスは、ローカルメモリ内のメタデータ、システムメモリが利用可能な最大ボクセル空間に割り当てられたスペースを割り当てることを決定します。このように、我々は永久歪みが発生する問題の大きさを避けます。しかし、メモリリークが発生すると、この場合には、ローカルメモリを多くかかります。あなたは、ローカルメモリ使用量でプロジェクトが異常に高いことが判明した場合。ああ、それはメモリリークです。
どのようにトラブルシューティングする方法
(1)によってjps
ID Javaプロセスを見つけます。
(2)top -p [pid]
最大メモリ使用量に到達見つける
(3)jstat -gccause pid 20000
20秒ごとに出力Full GC
結果を
(4)ことを見出しFull GC
何度も、基本的にメモリリークです。生成しdump
たドキュメントを、このツールは、あまりにも多くの援助をどのオブジェクト分析します。基本的な問題は、場所を特定することができるようにします。
例
図に示すようにStackOverflowの上、問題があります。
私はインタビューを持っていた、と私は、Javaでのメモリリークを作成するように頼まれました。私も1の作成を開始する方法についての手掛かりを持っていない、かなり間抜けに感じ言うまでもないです。
インタビューは、その後、メモリリークのためのプログラムを書くに突然無知な力は、非常に多くの首長が答えを与えられた人の質問を要求されているので、それは、おおよそ、です。
場合
「アルゴリズム」(第4版)帳からこの例のは、Iビットを簡略しました
class stack{
Object data[1000];
int top = 0; public void push(Object o){ data[top++] = o; } public Object pop(Object o){ return data[--top]; } }
データがスタックの内部からポップアップするとき、アレイ要素を指し示すデータはまた、ポインタを保持していました。あなたは、スタックが空でポップにもあれば、これらの要素は、メモリが回復されることはありません作り上げます。
解決策は、
public Object pop(Object o){
Object result = data[--top];
data[top] = null;
return result; }
ケースIIは、
実際には、これは、メモリリークの原因これらの例の理由が類似している、つまり、例の束であるストリームを閉じずに、具体的には、などのファイルストリーム、ソケットストリーム、ストリームデータベース接続、することができ
、次のように、ファイルストリームを閉じませんでした
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
...
...
} catch (Exception e) { e.printStacktrace(); }
別の例として、接続を閉じていませんでした
try {
Connection conn = ConnectionFactory.getConnection();
...
...
} catch (Exception e) {
e.printStacktrace();
}
ソリューションです。。。ああ、私たちはできるはずです。。あなたは転送されませんと言うclose()
方法を。
ケースIII
この場合の話をする前に、みんなThreadLocal
でTomcat
そこには、メモリリークの原因を知ることです。しかし、私はこのリークについて言わなければならない、とのThreadLocal自体がほとんどない関係を持って、私は基本的に不適切な使用に属し、与えられた例の公式ウェブサイトを見ました。
Tomcatの公式サイトでは、問題を記録します。アドレスは次のとおりです。https://wiki.apache.org/tomcat/MemoryLeakProtection
ただし、この例の公式ウェブサイトは、我々若干の修正を理解することは困難です。
public class HelloServlet extends HttpServlet{ private static final long serialVersionUID = 1L; static class LocalVariable { private Long[] a = new Long[1024 * 1024 * 100]; } final static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<LocalVariable>(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { localVariable.set(new LocalVariable()); } }
その後sever.xmlに配置されたconfに見て
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
150スレッド最大スレッドプール、4つのスレッドの最小
要求を受信し処理するための責任のTomcatコネクタコンポーネント、各への要求では、スレッドプールにスレッドを取ります。
今回の訪問でservlet
、ThreadLocal
追加された変数new LocalVariable()
が、インスタンスをないremove
ので、バックスレッドプールのスレッドを持つ変数。多くの訪問に加えて、servlet
同じスレッドメモリリークになりスレッドプールスレッド内部より多くの仕事につながる内部スレッドプールで動作しない場合があります。
また、内部生成の方法の使用時間。そして、オブジェクト解放されていません- > NO放出- > NO放出- > すべてのクラスがリリースされていないロードは、また、メモリリークが発生しました。servlet
doGet
new LocalVariable()
webappclassloader
LocalVariable
LocalVariable.class
webappclassloader
webappclassloader
また、あなたがeclipse
リロード操作を行っている、スレッドプールのスレッド内部の作業をすることは常に存在し、かつ内部のスレッドthreadLocal
変数がクリーンアップされていません。また、新しいを構築し、時間をリロードwebappclassloader
上記の手順を繰り返し、。メモリオーバーフローに数回、マルチリロード。
しかしTomcat7.0後、あなたはすべての時間を行うreload
には、スレッドプールスレッドの作業クリーンアップしますthreadLocals
変数を。したがって、tomcat7.0後にこの問題は、存在しません。
PS:ThreadLocal
利用Tomcat
サービス環境の下ではなく、すべてのWeb要求の操作手順は、ことに注意することがThreadLocal
ユニークです。ThreadLocal
何のライフサイクルと等しくないRequest
のライフサイクル。ThreadLocal
以来密、スレッドオブジェクトを結合したTomcat
スレッドプールのスレッドの使用が可能、再使用状況です。
序文
このトピックでは、書き込みがはい、本当にあるので、子供の靴の隣のブロガーは、最近と呼ばれる記事「ThreadLocalのメモリリーク、」記事を書いたので、私は、再び彼女を行った理由は、私は、リンクではないよ、すでに一般的です。。(百万本の言葉は省略)
私も無意味に頼まれた、仕上げに焦点を当てました。人道懸念のうち、ブロガーは非常に恥知らずを書きます。
テキスト
定義
大勢の人たちが、メモリオーバーフローやメモリリークの違いを理解していないので、まず、私たちはまず、定義について話す必要があります。
メモリ・オーバーフロー(OutOfMemoryを):あなただけの10ドルを持って、私はあなたが百であることがわかりました。ごめんなさい、ああ、私はそんなにお金を持っていません。(给不起)
メモリリーク(MemoryLeakは):あなたは10ドルを持って、私は1つのためにあなたを探しています。しかし、恥知らずなブロガーは、あなたにそれをすべてを与えることはありません。(没退还)
関係:複数のメモリリークがメモリオーバーフローを引き起こす可能性があります。(ブロガーがより多くのお金を数回あなたを見つけるために恥知らず、あなたはお金がない、真実です。)
害
[OK]を、私は、プロジェクト内の例のJavaプログラムより多くのカードを発生していません。
メモリリークが頻繁になりますのでFull GC
、およびFull GC
プログラムが停止し、最終的にクラッシュする原因となります。だから、あなたはあなたのプログラムより多くのカード、複数のカード、あなたは軽蔑されるプロダクトマネージャーを感じるだろう。ちなみに、私たちはチューニングJVM理由は、減少させることにあるFull GC
外観を。
私はプロジェクトがちょうどライン上で良いされているとき、私は一度会っていた覚えています。時間の蓄積の結果として、それが報告されましたOutOfMemoryError: PermGen space
。
それはこれに来るときはPermGen space
、電源の突然のバースト先史時代、本体ボーから噴き出す、メソッド領域を教えてください、それを越えて行く、結局のところ、これは「あきらめエントリからJVM。」について話されていません
メソッドエリア:Java仮想マシン仕様から、用スレッドシェアのそれぞれの実行時のメモリ領域。これは、格納、各クラスのコンフィギュレーション情報、例えば、実行時定数プール(Runtime Constant Pool
)、バイトコード・データ・コンテンツ・フィールドとメソッド、およびコンストラクタ通常の方法を。
上記内部異なる仮想マシンに実装ノルムが、同じではないが、最も一般的である(PermGen空間)の永久的な生成と素子間隔(メタスペース)。
jdk1.8前:実装面積が永久的な世代と呼ばれます。そのため非常に長い時間前に、ほとんどありませんJavaクラスの静的めったに、とはアンロードされ、回収ので、彼らが与えている恒久的な世代ブレアは言ったが。だから、あなたがプロジェクト内にある場合、ヒープおよび永続的な世代が、回収率は、単にこれは、メモリリークが発生することはほぼ確実であることはいうまでもない、ペースを維持することはできません減少していない、成長してきました。
jdk1.8後:エリアの実装は、元のスペースと呼ばれます。曲は非常に困難であることのJavaの永続的な世代。メタデータの生成はそれぞれに永久的であってもよいFull GC
出現移動します。そして、永久歪みを代入すると、空間の大きさを決定することは困難です。これにより、Javaクラスは、ローカルメモリ内のメタデータ、システムメモリが利用可能な最大ボクセル空間に割り当てられたスペースを割り当てることを決定します。このように、我々は永久歪みが発生する問題の大きさを避けます。しかし、メモリリークが発生すると、この場合には、ローカルメモリを多くかかります。あなたは、ローカルメモリ使用量でプロジェクトが異常に高いことが判明した場合。ああ、それはメモリリークです。
どのようにトラブルシューティングする方法
(1)によってjps
ID Javaプロセスを見つけます。
(2)top -p [pid]
最大メモリ使用量に到達見つける
(3)jstat -gccause pid 20000
20秒ごとに出力Full GC
結果を
(4)ことを見出しFull GC
何度も、基本的にメモリリークです。生成しdump
たドキュメントを、このツールは、あまりにも多くの援助をどのオブジェクト分析します。基本的な問題は、場所を特定することができるようにします。
例
図に示すようにStackOverflowの上、問題があります。
私はインタビューを持っていた、と私は、Javaでのメモリリークを作成するように頼まれました。私も1の作成を開始する方法についての手掛かりを持っていない、かなり間抜けに感じ言うまでもないです。
インタビューは、その後、メモリリークのためのプログラムを書くに突然無知な力は、非常に多くの首長が答えを与えられた人の質問を要求されているので、それは、おおよそ、です。
場合
「アルゴリズム」(第4版)帳からこの例のは、Iビットを簡略しました
class stack{
Object data[1000];
int top = 0; public void push(Object o){ data[top++] = o; } public Object pop(Object o){ return data[--top]; } }
データがスタックの内部からポップアップするとき、アレイ要素を指し示すデータはまた、ポインタを保持していました。あなたは、スタックが空でポップにもあれば、これらの要素は、メモリが回復されることはありません作り上げます。
解決策は、
public Object pop(Object o){
Object result = data[--top];
data[top] = null;
return result; }
ケースIIは、
実際には、これは、メモリリークの原因これらの例の理由が類似している、つまり、例の束であるストリームを閉じずに、具体的には、などのファイルストリーム、ソケットストリーム、ストリームデータベース接続、することができ
、次のように、ファイルストリームを閉じませんでした
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
...
...
} catch (Exception e) { e.printStacktrace(); }
別の例として、接続を閉じていませんでした
try {
Connection conn = ConnectionFactory.getConnection();
...
...
} catch (Exception e) {
e.printStacktrace();
}
ソリューションです。。。ああ、私たちはできるはずです。。あなたは転送されませんと言うclose()
方法を。
ケースIII
この場合の話をする前に、みんなThreadLocal
でTomcat
そこには、メモリリークの原因を知ることです。しかし、私はこのリークについて言わなければならない、とのThreadLocal自体がほとんどない関係を持って、私は基本的に不適切な使用に属し、与えられた例の公式ウェブサイトを見ました。
Tomcatの公式サイトでは、問題を記録します。アドレスは次のとおりです。https://wiki.apache.org/tomcat/MemoryLeakProtection
ただし、この例の公式ウェブサイトは、我々若干の修正を理解することは困難です。
public class HelloServlet extends HttpServlet{ private static final long serialVersionUID = 1L; static class LocalVariable { private Long[] a = new Long[1024 * 1024 * 100]; } final static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<LocalVariable>(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { localVariable.set(new LocalVariable()); } }
その後sever.xmlに配置されたconfに見て
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
150スレッド最大スレッドプール、4つのスレッドの最小
要求を受信し処理するための責任のTomcatコネクタコンポーネント、各への要求では、スレッドプールにスレッドを取ります。
今回の訪問でservlet
、ThreadLocal
追加された変数new LocalVariable()
が、インスタンスをないremove
ので、バックスレッドプールのスレッドを持つ変数。多くの訪問に加えて、servlet
同じスレッドメモリリークになりスレッドプールスレッド内部より多くの仕事につながる内部スレッドプールで動作しない場合があります。
また、内部生成の方法の使用時間。そして、オブジェクト解放されていません- > NO放出- > NO放出- > すべてのクラスがリリースされていないロードは、また、メモリリークが発生しました。servlet
doGet
new LocalVariable()
webappclassloader
LocalVariable
LocalVariable.class
webappclassloader
webappclassloader
また、あなたがeclipse
リロード操作を行っている、スレッドプールのスレッド内部の作業をすることは常に存在し、かつ内部のスレッドthreadLocal
変数がクリーンアップされていません。また、新しいを構築し、時間をリロードwebappclassloader
上記の手順を繰り返し、。メモリオーバーフローに数回、マルチリロード。
しかしTomcat7.0後、あなたはすべての時間を行うreload
には、スレッドプールスレッドの作業クリーンアップしますthreadLocals
変数を。したがって、tomcat7.0後にこの問題は、存在しません。
PS:ThreadLocal
利用Tomcat
サービス環境の下ではなく、すべてのWeb要求の操作手順は、ことに注意することがThreadLocal
ユニークです。ThreadLocal
何のライフサイクルと等しくないRequest
のライフサイクル。ThreadLocal
以来密、スレッドオブジェクトを結合したTomcat
スレッドプールのスレッドの使用が可能、再使用状況です。