torutkのブログ

ソフトウェア・エンジニアのブログ

JDK8のソースコード(標準API)を見る

今年9月リリース予定のJava SE 8は、現在開発途中のスナップショット版が週1回のペースで公開されています。(開発者向けプレビューの位置づけ)

Java SE 8で新たに導入されるDate and Time APIソースコードを見てみようとこのプレビュー版(3/14付のjdk8 b81)に含まれるsrc.zipを展開してみましたが、java.timeパッケージが含まれていません。そこで、jdk8のソースコードを入手して中を調べてみることにしました。

まず、JDK8のプロジェクトサイト(以下URL)へアクセスし、source のリンクを辿りました。

すると、バージョン管理リポジトリの変更/タグのサマリページに飛んでしまいます。ここにbz2/zip/gzといったリンクがあるので、これをクリックすれば一式ダウンロードできるかと思い、bz2を落としてみましたが数百KBのアーカイブファイルでしかありません。中を見て、インストール手順の説明を見たところ、バージョン管理ツール(Mercurial)でまずjdk8のクローンを作り、次にその中に含まれるソースコード入手用シェルスクリプトを実行するとありました。

ということで、Mercurialおよびシェルスクリプト実行が必要になります。Windowsマシンを使っているので、ここはCygwinMercurialを追加インストールして臨むこととしました。

 $ hg clone http://hg.openjdk.java.net/jdk8/jdk8 openjdk8
 $ cd openjdk8 && sh ./get_source.sh

get_source.shには時間がかかるので、珈琲を淹れて待っているとよい感じです。

ここで、当初の目的はjava.time.LocalDateクラスのインスタンスがどれだけメモリを使用するのかを、ソースコードを見てインスタンスフィールドの内容を調べて確認することです。

そこで、展開された中からこのソースコードを探します。JDKの標準APIは、hgで生成したリポジトリopenjdk8の中のjdk/src/share/classesの下にパッケージ名に対応するディレクトリでソースコードが存在します。

java.time.LocalDateのソースコードを見た結果、インスタンスフィールドは次の3つでした。また、スーパークラスjava.lang.Objectなので、Object型のインスタンスが使用するメモリを加えれば大よそのメモリ使用量がわかります。

  • int year
  • short month
  • short day

intは4バイト、shortは2バイトなので、Object型の8バイト+LocalDate型の(4+2+2)バイトで16バイトがLocalDate型のインスタンス1つが使用するメモリ量想定値です。

以前、java.util.Calendar型をデータクラスのフィールドに使ってしまい、メモリ消費量が著しく増えて困ったことがありました。調べたらCalendar型のインスタンスは確か3ないし4百バイトのメモリ使用量でした。100万個のデータだと300MBがCalendarインスタンスで占められてしまいます(32bit JavaVMだとヒープ上限がほぼ1GBなので支配的)。

java.time.LocalDateなら大量のデータ件数に使うクラスで使ってもよさそうな大きさです(100万個でも16MB)。