のた犬のうまい猫めし

どら猫が作る、のた犬のための飯、略称、どら飯について語りつつ、各種技術、経済系セミナーに参加した報告、OSSいじってみた等のネタを入れていきます。更新情報はtwitterの@nota_inuにて。

Java女子部セミナー「JVMのいろは」日本電信電話株式会社OSSセンタ 久保田祐史氏

 

後日公開された資料:

JVM のいろはにほ #javajo

 

ここ(今回のセミナー)ではJVM=HotSpot VM。OpenJDK/OracleJDK。Oracleから落とせるJavaのこと。java Dukeのように実行するところがJavaVMの出番。Java仮想マシンJavaバイトコードの実行環境。書いたコードがどこでも動くようにするもの。主な機能として、コードを実行するための機能、メモリの管理(プログラマがやらなくていい分、こちらがやらなきゃいけない。ガベッジコレクタとか)。コードを実行するためにはクラスの存在を知り、ロードし、検証(パッケージ情報を識別するとか。ロードしただけで放置ではない)するクラスローダがある。インタプリタJITコンパイラが、メソッドの要求する命令、計算を実行する。

  • JVMJREJDKの違い? →とりあえずJDKでOK。JVM、クラスライブラリを合わせたのがJREJava Runtime Environment)、それに開発ツール(javac)を含めたのがJDK。最小限だけの場合JREだが、トラブルシューティングのためJDKも入れたほうがよい。客先に入れる場合にはマイナーバージョンも合わせたほうがよい。(Versionをどうやって確認するかも必ず事前に見ておくこと。Linuxの場合にはrpm -qa | grep javaWindowsの場合もスクリーンショットとって送ってもらう。)
  • クラスローダとは? →クラスファイル(.class)を動的にメモリ上にロードする機能。必要な時(たいていは起動した瞬間だが具体的な説明は困難。クラスパスに通すと実行した瞬間に読み込む)にロード。複数あり、親子関係を持つ。Javaで書かれている。
  • インタプリタ? →バイトコード中間言語)を逐次解釈しながら実行する。OSが直接実行するより遅い。よく使われるのは機械語にして高速化するのがJITコンパイラ。(Just in time。じっと、と読む)実行回数が規定値を超えたもののみコンパイル。(これを超えた、という明確な基準は不明。)
  • 開発者が意識するポイントは? →知りたい人だけ知ってればよい。なんとなくなイメージだけとらえていれば。このレベルで高速化することはほぼない。ただNoClassDefFoundErrorが出たらクラスローダの仕組みを理解するとき。IBM資料(http://www.ibm.com/developerworks/jp/websphere/library/java/j2ee_classloader/index.html)、@ashigeru 氏が作ったSlideShareの資料(http://www.slideshare.net/ashigeru/classloader)がよい。ソースを変えずにデバッグしたい場合(jarだけある)、バイトコートインジェクション。(例:ツールとしてbyteman。)挙動だけ見ることができる。

クラスローダーについて

 

 

  • JITコンパイル方法を知りたい:JavaDayTokyo2014資料がよい。(http://researcher.watson.ibm.com/researcher/files/jp-ISHIZAKI/PPL_SummerSchool2004_ishizaki.pdf とかかな。)だが、知りたい機会はほぼこない。
  • Javaのメモリ構造は? →HeapとNonHeap(非ヒープ)、JVMは主にCヒープを使う。HeapとNon Heap合わせてHeapと呼ぶことも。HeapはYoung世代、Tenured(Old)世代、非Heapは世代なし(Permanent。JDK8以降はMetaspace)。YonungはさらにEden、Survivor1、Survivor0がある。
  • Heapわけの理由は? →複数GCガベージコレクション)を利用するため。停止時間を短くするために複数ある。YoungがMinor GC、TenuredはMajorGC。アプリケーションがずっと動いていてオブジェクトが不要にならないとTenured。若くてどんどん死ぬものはYoung。MajorGCは大きな空間を見るのでそれに向いているアルゴリズム。範囲広くてしっかり、な感じ。
  • OutOfMemoryError(OOMEと略されるらしい!)の原因をどうやって確認する? →そのときにメモリ周りを意識することに。メモリリークか、メモリ不足か、バグか。(Slideshare oomeで検索すると説明資料が出てくる。http://www.slideshare.net/YujiKubota/javalangoutofmemoryerror-java)まずはOOMEの後にすぐ出るメッセージを確認。Java.heapと書かれているとHeap。リークか不足か。ヒープ使用量をグラフ化して確認する。増えたり減ったりしつつも増えすぎている場合、急にどんと増える場合(アクセスが増えてセッション維持して回収できない場合等)。YoungとOldは、参照があるかどうかの違い。不要になったタイミングでGCで回収される。YoungとOldの違いは、オブジェクトの年齢で、参照され続けてオブジェクトが長生きしていたらYoungからOldへ移動する。参照が無くなったら不要になり、不要になったタイミングでGCで回収される。(脚注:講師に修正ご指摘いただきました。ありがとうございます。)まずEdenに入り、次にSurvivor0に入り(例:Bufferがcloseしたら捨てる、Webアプリでセッション作ってオブジェクトがどんどん増えてブラウザが切られてセッションが終わったら参照も切れてGCがそのタイミングで。(SlideShareCMS GCで検索すると出てくるスライド参照。GCログの読み方等が書かれている。

    http://www.slideshare.net/YujiKubota/concurrent-marksweep-garbage-collection )

 

java.lang.OutOfMemoryError #渋谷java

 

 

Concurrent Mark-Sweep Garbage Collection #jjug_ccc

 

 

  • GCを見るには? →GC Viewer。GCのログを指定して読み込ませてやる。Full GC LineとUsed Heapを表示するとよい。Full GCが発生しても右肩上がりならリークしている。
  • いつ見ればよい? →結合試験あたり。OutOfMemoryErrorが出るか、性能試験のときか、あたりで見ればよい。アプリケーション停止時間が見られるので、10秒とかなっている場合にはメモリ増やすなりチューニングする。(Heapメモリ。OSのメモリではなくHeapだけに関係する。OOMEはCヒープよりむしろHeap。)
  • OutOfMemoryErrorとは? →ExceptionではなくError。一貫性がなく不安定。意図しない動作。情報を取ったらすぐ殺す。HeapDumpを取るオプションがある。CoreDumpを取るオプションもある。メッセージ種別によって原因がいくつかある。Java heap space(-Xmxで指定した以上のヒープを利用しようとした場合。ログからの調査。GCログはloggc、PrintGCDetailsで確認。ヒープダンプから分析。PrintClassHistogramでクラスがどれだけとっているか。←HeapStatusで全部見える)、GC overhead limit exceeded(GCが頻発して時間的な閾値を超えた。98%。GCががんばっても回収間に合わない。メモリ不足で落ちる。OracleJVMでよく発生)、unable to create new native thread(スレッド作成上限。procfsのVmHWM、free等で確認。Xssかメモリ増設。JMX、jconsole、jstack等でスレッド数を確認。OSでスレッド数を変えることもできるが責任はとれない)、could not allocae Unicode String(String作るときに入らない。JDK6ではPermGem、7以降はHeapを増やす、とりあえずString縮める)、PermGen space(設定値の変更する。JVMロード総クラスサイズの見積もりミス。付加試験を行い、HeapStatsかGCログで最大サイズ測定。PrintGCDetailsで表示できる)……。
  • 自分たちが作っていないクラスが増えている場合? →JVMのバグの可能性も疑える。
  • コードをどう直すべき? →ぐぐる

 

【HeapStats】

障害が起こった時に障害解析したいが、分析の前準備が煩雑で、障害の再現待ちとか手作業での解析とかで時間がかかるが、HeapStatsを使うことでログを常時収集しつつ、メモリリークの予知検知し、SNMPトラップで流せる。5%以下の低オーバヘッドで常時収集。
インストールはrpm(中身が一部アセンブラなのでWindowsは動かない)。Javaの起動オプションを一つ追加でOK。実行中のJavaプロセスに設定することも可能。オブジェクトの参照関係を表示できる。(フレームワークのことも見える。)

AnalyzerはSWINGからJavaFXへ。より直感的になる予定。OSSとして公開済み(詳細は http://icedtea.classpath.org/wiki/HeapStats/jp)。CodeZineに解説記事がある。 


知らないなんてもったいない! 障害発生の原因を洗い出すOSSのJavaVM解析支援ツール「HeapStats」を使ってみよう (1/5):CodeZine

 

【参考】

以前のHeapStatsに関するセミナーについて:


JavaOne 2014 報告会「HeapStats の発表と出展を通して見えた JavaOne2014」高雄 慎二氏 - のた犬のうまい猫めし