発表ネタ - JJUG CCC 2016 Spring向け¶
発表スライド |
企画概要¶
セッション名:「JavaデスクトッププログラムをふつーのWindowsプログラムのように配布・実行する方法とPCの動きが重くならないよう気を付けること」
対象聴講者:Javaで作ったWindowsデスクトップで実行するプログラムを、普通のWindowsプログラムのように簡単に配布、インストール、実行、アップデート、アンインストールしたい人。
アジェンダ(ほぼ最終)¶
- Javaプログラムを使ってもらう
Javaプログラムをふつうの利用者に配布して使ってもらうために望ましいこととして、配布・インストール・実行が簡単なこと、PCが重くならないことを掲げる - Windowsインストーラー
ふつうの利用者が経験しているインストールと実行に倣うには、JDKのjavapackagerを使ってJavaプログラムをWindowsインストーラーとする - メモリとCPU
JavaVM 64bit版はCPU・メモリを大食いする。ハイパースレッディングの弊害、メモリの測定と削減について - 簡単につくる
NetBeans IDEなら、Windowsインストーラーを簡単に作成 - あれこれ注文をつける
javapackagerで作成したインストーラーでは対応できないことと、対応の仕方
説明とデモを半々の予定
検討経過¶
ふつうのWindowsプログラム¶
配布・実行¶
- プログラムのインストーラを入手し実行するとプログラムが所定の場所にインストールされる
- インストール後はスタートメニューから、あるいはデスクトップのショートカットから、あるいは検索結果から実行する
- コントロールパネルのプログラムのアンインストールからインストールされているか、バージョン番号が確認できる
- ファイルが消えたといったトラブル時は修復が可能
- 新しいバージョンがリリースされたらそのインストーラを入手して実行するとプログラムが新しいバージョンに更新される
- 不要になったらアンインストールする
CPUとメモリリソース¶
デスクトップ上でメインで使用するプログラムと、デスクトップ上に常駐して動くプログラムがあります。前者はそれなりにCPUとメモリリソースを喰っても許容されますが、後者がCPUやメモリリソースを喰うと嫌われます。
デスクトップ上に常駐して動くプログラムの例として、アナログ時計を動かしてみたところ、しばらくするとPCのファンがうなり始めました。
Javaでプログラムを作った、さあ、次はどうする?¶
- JARファイル群、設定ファイル群と起動バッチファイル
- 実行可能JARファイル
- 依存ライブラリのJARは別出し(相対パスを維持)
- 一つのJARファイルにまとめてしまう
- インストーラー
インストール方法の比較¶
比較項目 | インストール方法 | ||
ファイル群を固めて展開 | 実行可能JARファイル | インストーラー(MSI) | |
配布ファイル数 | 1個 | ||
インストール手順数 | 多い | 少ない | |
配布 | なし | なし | Active Directory他 MSI配布機能を持つものあり |
ヘルプ等付属ファイル | 可能 | 別 | 可能 |
アップデート | 手作業 | インストーラー任せ | |
削除 | 手作業(数多い) | 手作業(数少ない ) | インストーラー任せ |
修復 | 不可 | インストーラー任せ | |
現バージョンの確認 | バージョン識別手段を埋め込んだ上で手作業 | コントロールパネルや管理コマンドで確認 | |
JVMの指定 | 起動スクリプトで可 | 不可 | ビルド時に選択 |
JVMオプションの指定 | 起動スクリプトで可 | 不可 | ビルド時に指定? |
設定ファイルの扱い |
- JAR実行ファイルについては、1つのファイル(≠アーカイブ)のみでかつダブルクリックで実行することを前提とする
- インストーラーについては、javapackagerで生成するMSI形式に限定する?要検討
- インストール先については、Windows OSのファイルシステムのポリシーに従い、Program Files、ProgramData、ユーザーAppDataの3箇所に分散配置する
インストール方法¶
ケース1)単一ファイルで実行(好きなところにおいてダブルクリックで実行)
ケース2)インストーラでインストールして実行
プログラムを多数動かす¶
昨今のデスクトップPCは、64bit OS、マルチコア、搭載メモリも8~16GB以上と一昔前のサーバー並みとなっている。
Java VM(64bit版)をデフォルト設定で起動すると、エルゴノミクス機能によりサーバー機と判断、使用するメモリ(-Xmxで指定する最大ヒープサイズ)は搭載メモリの1/4、パラレルGCを使用、JITコンパイラもC2コンパイラが使用される。
この設定で、同一PC上でJavaで作ったプログラムを多数実行すると、かなりすごいことになる。
- CPU使用率がどんどん増える
- メモリがどんどん増える
CPU使用率について¶
メモリ使用について¶
- デフォルトのガベージコレクタ
Windows版のJavaは、32bit版はシリアルGC、64bit版はパラレルGCを使用 - デフォルトのメモリ
- Javaヒープサイズ(例は16GBメモリ搭載PCの場合)
初期値(-Xms):搭載メモリの1/64 例)256MB <-- プロセスのコミットサイズ
最大値(-Xmx):搭載メモリの1/4 例)4GB <-- プロセスのバーチャルメモリ
- Javaヒープサイズ(例は16GBメモリ搭載PCの場合)
物理メモリ8GBを搭載したPCでの主要メモリ使用量の値を-XX:+PrintFlagsFinalで確認
32bitクライアントJVM¶
uintx InitialHeapSize := 16777216 uintx MaxHeapSize := 268435456 uintx MetaspaceSize = 12582912
32bitサーバーJVM¶
uintx InitialHeapSize := 67108864 uintx MaxHeapSize := 734003200 uintx MetaspaceSize = 16777216
64bitサーバーJVM¶
uintx InitialHeapSize := 134217728 uintx MaxHeapSize := 2128609280 uintx MetaspaceSize = 21807104
ツール¶
Process Explorer¶
プロセス一覧から対象プロセスを選択し、詳細でプロセスが使用する仮想メモリ、物理メモリ量が確認できる
仮想サイズは、仮想アドレス空間のうちプログラムが使用すると枠を確保したサイズ(ページが予約またはコミットであるものの合計)
プライベートバイトは、仮想サイズの中で実際に使用しているサイズ(ページがコミットであるものの合計)
ワーキングセットは物理メモリ上に存在するサイズ(ページがコミットでかつ物理メモリ上にページが割り当てられているものの合計)
仮想サイズが大きくても、コミットされるメモリが少なければPCの動きには影響をほとんど与えない。
WiX toolset¶
Windows Installer(MSI)を作成するツール。
WiX
Java Flight Recorder/Java Mission Control¶
Java Platform, Standard Editionトラブルシューティング・ガイド
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/troubleshoot/toc.html
NetBeans IDE¶
Windowsインストーラー形式ファイルをビルドする機能
https://netbeans.org/kb/docs/java/native_pkg_ja.html
デスクトッププログラムのチューニング(起動オプション)¶
- 32bit版JVMを使う
- 32bit版JVMがインストールされている
- 32bit版JVMがインストールされていない
javapackagerで、32bit版JVMを含める
- 64bit版JVMを(仕方なく)使う
起動オプションでできるだけ省リソース設定をする
技術情報リファレンス¶
- Oracle Java SE JDK/JREのレジストリについて
http://docs.oracle.com/javase/8/docs/technotes/guides/install/windows_jdk_install.html#CHDJCCEG
"Private Versus Public JRE"節に、レジストリキーについて言及あり - Microsoft Windows ディレクトリの基準(→ 文書リンク切れにつき・・・)
- WiX Toolset
http://wixtoolset.org/
- Windows の限界に挑む: 物理メモリ
- Windows の限界に挑む: 仮想メモリ
- Windows の限界に挑む: ページ プールと非ページ プール
- Windows の限界に挑む: プロセスとスレッド
書籍¶
- 「Javaパフォーマンス」
http://www.oreilly.co.jp/books/9784873117188/
JDK 9関連¶
JDK 9でJava自体のモジュール化が導入されることで(Project Jigsaw)、javapackagerでバンドルするJREをプログラムが必要とするもののみに減らすことができるようです。
http://openjdk.java.net/jeps/275
未整理¶
デモ¶
PowerShell から多数のプログラムを実行¶
PS > 0..10 | foreach { $y = $_ * 100; javaw -jar dist\AnalogClockSvg.jar --y="$y" --scale=0.75}
javapackagerでWindowsインストーラ(MSI)ファイルの作成¶
NetBeans IDEでWindowsインストーラ(MSI)ファイルの作成¶
Javaプログラムのメモリ、CPU¶
javapackager¶
- JavaアプリケーションのJARファイル自身の生成には、jarコマンドを使うのが推奨(Oracle)
- javapackagerでJavaアプリケーションをパッケージ化するにはant-javafx.jar(Antタスク)を使うのが推奨(Oracle)
∵ 柔軟性がなく、オプションも少ない