プロジェクト

全般

プロフィール

発表ネタ - JJUG CCC 2016 Spring向け

発表スライド

企画概要

セッション名:「JavaデスクトッププログラムをふつーのWindowsプログラムのように配布・実行する方法とPCの動きが重くならないよう気を付けること」
対象聴講者:Javaで作ったWindowsデスクトップで実行するプログラムを、普通のWindowsプログラムのように簡単に配布、インストール、実行、アップデート、アンインストールしたい人。

アジェンダ(ほぼ最終)

  1. Javaプログラムを使ってもらう
    Javaプログラムをふつうの利用者に配布して使ってもらうために望ましいこととして、配布・インストール・実行が簡単なこと、PCが重くならないことを掲げる
  2. Windowsインストーラー
    ふつうの利用者が経験しているインストールと実行に倣うには、JDKのjavapackagerを使ってJavaプログラムをWindowsインストーラーとする
  3. メモリとCPU
    JavaVM 64bit版はCPU・メモリを大食いする。ハイパースレッディングの弊害、メモリの測定と削減について
  4. 簡単につくる
    NetBeans IDEなら、Windowsインストーラーを簡単に作成
  5. あれこれ注文をつける
    javapackagerで作成したインストーラーでは対応できないことと、対応の仕方

説明とデモを半々の予定

検討経過

ふつうのWindowsプログラム

配布・実行

  1. プログラムのインストーラを入手し実行するとプログラムが所定の場所にインストールされる
  2. インストール後はスタートメニューから、あるいはデスクトップのショートカットから、あるいは検索結果から実行する
  3. コントロールパネルのプログラムのアンインストールからインストールされているか、バージョン番号が確認できる
  4. ファイルが消えたといったトラブル時は修復が可能
  5. 新しいバージョンがリリースされたらそのインストーラを入手して実行するとプログラムが新しいバージョンに更新される
  6. 不要になったらアンインストールする

CPUとメモリリソース

デスクトップ上でメインで使用するプログラムと、デスクトップ上に常駐して動くプログラムがあります。前者はそれなりにCPUとメモリリソースを喰っても許容されますが、後者がCPUやメモリリソースを喰うと嫌われます。

デスクトップ上に常駐して動くプログラムの例として、アナログ時計を動かしてみたところ、しばらくするとPCのファンがうなり始めました。

Javaでプログラムを作った、さあ、次はどうする?

  1. JARファイル群、設定ファイル群と起動バッチファイル
  2. 実行可能JARファイル
    • 依存ライブラリのJARは別出し(相対パスを維持)
    • 一つのJARファイルにまとめてしまう
  3. インストーラー

インストール方法の比較

比較項目 インストール方法
ファイル群を固めて展開 実行可能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 <-- プロセスのバーチャルメモリ

物理メモリ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

プロセス一覧から対象プロセスを選択し、詳細でプロセスが使用する仮想メモリ、物理メモリ量が確認できる

processexplorer-1.png

仮想サイズは、仮想アドレス空間のうちプログラムが使用すると枠を確保したサイズ(ページが予約またはコミットであるものの合計)
プライベートバイトは、仮想サイズの中で実際に使用しているサイズ(ページがコミットであるものの合計)
ワーキングセットは物理メモリ上に存在するサイズ(ページがコミットでかつ物理メモリ上にページが割り当てられているものの合計)

仮想サイズが大きくても、コミットされるメモリが少なければ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を(仕方なく)使う
    起動オプションでできるだけ省リソース設定をする

技術情報リファレンス

書籍

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)
    ∵ 柔軟性がなく、オプションも少ない


ほぼ7年前に更新