Javaに関連するTips。今後はJavaで実装する機会も少なくなるとは思うけど、おりにふれて追記していく予定。
インストール
インストール
# 最新バージョンのインストール
brew cask install java # 2019年4月現在だとjdk12がinstallされる
# 過去バージョンのインストール
brew tap homebrew/cask-versions
# brew cask install java8 #配布停止ずみ
brew cask install adoptopenjdk8
brew cask install java11
JAVA_HOME確認
/usr/libexec/java_home -v 1.8
> /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
/usr/libexec/java_home -v 11
-> /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home
/usr/libexec/java_home -v 12
-> /Library/Java/JavaVirtualMachines/openjdk-12.0.1.jdk/Contents/Home
JAVA_HOME切り替え
aliasを設定しておき、java12
, java8
のような感じで切り替える
alias java8='export JAVA_HOME=`/usr/libexec/java_home -v 1.8`'
alias java11='export JAVA_HOME=`/usr/libexec/java_home -v 11`'
alias java12='export JAVA_HOME=`/usr/libexec/java_home -v 12`'
メモリ調査関係
ローカルで動いているjavaの監視
- GCの実行
- ヒープダンプ取得
jvisualvm -J-Xmx1024m
jConsole
- メモリ使用状況をリアルタイム監視
- 外からGCをかけられる
java プロセスIDを調べる
jps -l
GCの手実行
jcmd ${プロセスID} GC.run
thread dumpの取得
jstack ${プロセスID} > ${ファイル名} # hoge.tdump
heap dumpの取得
df -h /${対象フォルダ}
jmap -dump:format=b,file=${ファイル名} ${プロセスID} # hoge.hprof
Eclipse Memory Analizer
- Eclipse Plugin
- ローカルPCで実行中のJVMやGCダンプを取り込んで分析
- 実行中のJVMを分析する場合、取り込んだタイミングで、いったんdumpファイルが作成される
- 1Gクラスのdumpファイルを解析するには、それを読み込む必要がありそれだけで数分かかった・・・
- Leek suspects -> Dominator Treeを見ていくと、メモリリークしているオブジェクトが分かる
- 「Shallow Heap」はそのオブジェクト自体のサイズ。「Retained Heap」はそのオブジェクト+子オブジェクトの合計サイズ
- 子オブジェクトの「Retained Heap」の合計 + 自オブジェクトの「Shallow Heap」 = 自オブジェクトの「Retained Heap」
- 同じオブジェクトを複数オブジェクトから参照している場合、ダブルカウントされるかどうか、よく分からず?
テスト
jMockitoで実行時の挙動を上書き(static methodもOK)
new MockUp<Hoge>() { // 対象のクラスを指定
@Mock
public void fuga(Invocation inv, final Request request, final Response response) { // 属性、メソッド名、引数は合わせる
// do something
inv.proceed();
}
};
リフレクション
フィールドの値を取得して書き換える
Class<Hoge> clazz = Hoge.class;
// このクラスから参照不可能なものも含めた全フィールド一覧取得
Field[] declaredFields = clazz.getDeclaredFields();
// このクラスから参照不可能なものも含めたフィールド取得
Field declaredField = clazz.getDeclaredField('fuga');
// このクラスから参照可能なフィールド一覧取得
Field[] fields = clazz.getFields();
// このクラスから参照可能なフィールド取得
Field field = clazz.getField('fuga');
// 値の設定
Hoge hoge = new Hoge();
field.set(hoge, "dummy_string");
input stream
String <=> Input Stream
// String -> Input Stream
String input = "0000000001\n0000000002\n0000000003";
InputStream is = new ByteArrayInputStream(input.getBytes("utf-8"));
// Input Stream -> String
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
reader.lines().forEach(line -> {});
その他
時間計測
long start = System.currentTimeMillis();
//do something
long stop = System.currentTimeMillis();
System.out.println("実行時間: " + (stop - start));