*目次 [#v4a08371]
#contents

*解消事例 [#xbdd9eda]
**tomcatとjdbcとjava7 [#m6109cd6]
http://ameblo.jp/vashpia77/entry-11486039940.html

*メモリリークをどのように発見するか(英語) [#j232740e]
http://stackoverflow.com/questions/40119/how-to-find-a-java-memory-leak

*JAVAヒープサイズ・GCチューニングのまとめ [#s9181bc3]
http://ise0615.blogspot.jp/2010/06/javagc.html

*Java標準装備のGUIプロファイラーjvisualvm [#l9704c27]

**解説ページ [#od2d2a76]
http://visualvm.java.net/ja/intro.html


いろいろ下にかいてありますが、

 jvisualvm.exe

が便利です。

**jvisualvm.exe紹介ページ [#h10a6753]
http://www.atmarkit.co.jp/fjava/column/andoh/andoh43.html

**リモートホストへの接続 [#dfefccd3]

***本家の説明 [#f2c7e1b4]
http://visualvm.java.net/ja/gettingstarted.html

***設定方法 [#k3e86066]
http://d.hatena.ne.jp/tanamon/20091016/1255674058

リモートアプリケーションからデータを取得するには、リモートの JVM で jstatd ユーティリティーが実行されている必要がありますリモートホストで実行中のアプリケーションはプロファイルできません。

※ただし、デフォルトのポートは1099を使っており、セキュリティ的にポートが閉じられていると思います。

なので、jvisualvmをリモートで接続できない場合があると思います。

でもjvisualvmはヒープしたダンプファイルを読み込むことができ、かつ比較する機能を持っています。

sshで入れるならば、sshでリモートサーバに接続して、すでにプロセスが動いているとおもうので、
 ps aux
でプロセスをしらべて、比較的負荷の少ない時間帯にjmapを行います。

自分だと
 ps aux | grep tomcat | awk '{print $2 " " $1}' | grep tomcat | awk '{print $1}'

こんな感じで、出てきたプロセスIDをxargsの-Iオプションで、パラメータとしてつかうとかしています。

それはさておき、

しばらくして、メモリリークが起きてそうなころあいを見計らって、もう一度jmapを行い、ダンプを2回とります。それは、差分をとるためです。

scpコマンドでファイルをローカルにダウンロードしてきます。

あとは、jvisualvmを使ってヒープを比較するのです。


***jstatd を起動する方法 [#led09354]

http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstatd.html

***not respondingエラーが出る場合 [#xf188f3e]
Unable to open socket file: target process not responding or 
      HotSpot VM not loaded

そんなときは-Fオプションを使えばいいよ。

http://www.acroquest.co.jp/webworkshop/JTSMM/backnumber.cgi?id=123545895410751


*すでに存在しているページ [#c80a2373]
すでにまとめられているページがあるので、とりあえずそちらをご覧ください。
このページはそれらのページのつまみ食いという感じです。

**Javaメモリ、GCチューニングとそれにまつわるトラブル対応手順まとめ [#hc2bc33d]
http://d.hatena.ne.jp/learn/20090218/p1

**JavaアプリのメモリリークやOutOfMemoryErrorの調査方法について [#ldfffb7e]
http://www.syboos.jp/java/doc/how-to-do-when-OutOfMemoryError.html


*jconsole [#x9a5222e]

**JVMの起動オプションに次のパラメータを追加する [#l9cdb97c]
たとえばポート8082で動かしてみたいとする

 -Dcom.sun.management.jmxremote.authenticate=false
 -Dcom.sun.management.jmxremote.ssl=false
 -Dcom.sun.management.jmxremote.port=8082

**つなぎ方 [#a93c2897]
たとえばポート8082で動いているとする
 jconsole localhost:8082

*hprof [#tdc73634]
JVMTI を利用したプロファイラエージェントで、ヒープや実行時間のプロファイリングなど基本的な機能が提供されている。


*hprof を利用するには [#va5cd2b5]
-agentlib:hprof

これでも利用できますが、よりビジュアルに結果を見るために、eclipseでMemory Analayzer のプラグインが提供されています。

*ヘルプの出し方 [#a6970211]
下記のコマンドでヘルプを見ることができる
 java -agentlib:hprof=help

**何の略か [#n1494841]
 HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)

**使い方 [#a15e46c5]
hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]

**オプション [#w9e640fd]
 Option Name and Value  Description                    Default
 ---------------------  -----------                    -------
 heap=dump|sites|all    heap profiling                 all
 cpu=samples|times|old  CPU usage                      off
 monitor=y|n            monitor contention             n
 format=a|b             text(txt) or binary output     a
 file=<file>            write data to file             java.hprof[{.txt}]
 net=<host>:<port>      send data over a socket        off
 depth=<size>           stack trace depth              4
 interval=<ms>          sample interval in ms          10
 cutoff=<value>         output cutoff point            0.0001
 lineno=y|n             line number in traces?         y
 thread=y|n             thread in traces?              n
 doe=y|n                dump on exit?                  y
 msa=y|n                Solaris micro state accounting n
 force=y|n              force output to <file>         y
 verbose=y|n            print messages about dumps     y

**Obsolete Options [#r5125362]
 gc_okay=y|n

**例 [#u63e41f3]
  - Get sample cpu information every 20 millisec, with a stack depth of 3:
      java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname
  - Get heap usage information based on the allocation sites:
      java -agentlib:hprof=heap=sites classname

**メモ [#d7bab5ca]

-The option format=b cannot be used with monitor=y.
-The option format=b cannot be used with cpu=old|times.
-Use of the -Xrunhprof interface can still be used, e.g.
       java -Xrunhprof:[help]|[<option>=<value>, ...]
    will behave exactly the same as:
       java -agentlib:hprof=[help]|[<option>=<value>, ...]

**注意 [#f3696783]
-This is demonstration code for the JVMTI interface and use of BCI,
    it is not an official product or formal part of the JDK.
-The -Xrunhprof interface will be removed in a future release.
-The option format=b is considered experimental, this format may change
    in a future release.


**デフォルト出力 [#s0058e15]
デフォルトではプロファイル結果はjava.hprof.txtというファイルに出力されます


*日本語で紹介しているサイト [#t3d267f1]

**Java/hprof(jvmpi) [#gb27fe23]
http://apis.jpn.ph/fswiki/wiki.cgi?page=Java%2Fhprof%28jvmpi%29

**Javaでヒープダンプの取得/解析メモ その1 [#tb1a2e57]
http://lenemarix2.blog28.fc2.com/blog-entry-16.html


***JavaアプリのPIDを調査 [#q49cb3a1]
 jps -l

***スレッドダンプ [#n2e6fe61]
 jstack PID

***ガーベッジ・コレクションのスナップショット [#g9690ef3]
 jstat -gc 5756 250 10

 
***jmap [#t6430fd8]
プロセス番号を調べてからつかいます。



自分はcygwinとかいれているので、

 tasklist | nkf | grep java

とかで調べています。



バイナリファイルで結果を出力する例
 jmap -dump:format=b,file=出力ファイルパス プロセス番号

出てきたファイルを見るには
 jhat -J-Xmx700m jmapでの出力ファイルパス

*Eclipse Memory Analyzer [#v6473080]
以下紹介サイトより抜粋

-Leak Suspects - リークしてそうなのはこいつらだ
-Dominator tree - 大きいオブジェクトを一覧で見よう
-Path to GC Roots - こいつは誰が参照してる?
リークを特定する為の基本的な流れとしては、Leak Suspects で怪しいところを教えてもらい、Dominator Tree*1 で怪しいオブジェクトを一覧 & 構造を調べ、Path to GC Roots でリーク元を特定する、という様な流れになります。

詳しくは下記の紹介サイトをごらんください。

**公式サイト [#p1ef8d1f]
http://eclipse.org/mat/downloads.php

**インストール紹介サイト [#v912d614]
http://xiangcai.at.webry.info/201009/article_7.html

※現時点では、MATの更新サイトのアドレスがバージョンアップで変更になっていました。
http://download.eclipse.org/mat/1.2/update-site/

**紹介サイト [#cce1c24e]
http://tlync.hateblo.jp/entry/20111220/1324372308

**使い方メモ [#r4be3fef]

1.Eclipseのプラグインなので適当にインストール。

2.Eclipseの実行の構成を開いて、引数タブのVM引数に以下のどちらかを設定する。



hprofファイルだけを出力します。
 -Xrunhprof:heap=dump,format=b,file=./${project_name}.hprof

hprofファイルも出力されるけど関係ないファイルが全部出力される。
 -agentlib:hprof=heap=dump,format=b

3.普通に実行

4.hprofファイルが出力されるので開くと、メモリの使用状態が表示される。

***Eclipseでtomcatの場合 [#k629cb96]

http://wiki.eclipse.org/index.php/MemoryAnalyzer#Getting_a_Heap_Dump
http://tomcat.10.x6.nabble.com/How-to-generate-heap-dump-in-Tomcat-5-5-Windows-td4643861.html


***情報源 [#p1f16f5c]
http://odasusu.hatenablog.com/entry/20080730/1217419266

*PrintClassHistogramオプション [#q1f068d7]

そのプロセスに対して一定間隔ごとにSIGQUITシグナルを送信する。

**利用方法 [#dd5fe57d]
Java起動時に以下のオプションを追加する
 java -verbose:gc -XX:+PrintClassHistogram TestMain

***UNIX系で情報を取得 [#b266e683]
crontabで実行するコマンド
 kill -3 <java pid>


***情報源 [#d999e061]
http://www.atmarkit.co.jp/fjava/rensai4/troublehacks08/troublehacks08_2.html


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS