覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Javaオブジェクトのメモリサイズを取得するためのツール群

Javaでの開発をしている際に、Javaオブジェクト(インスタンス)のメモリサイズを把握したい場合があると思います。
そのような場合に役に立つツール群を以下に記載しました。
これらを使えば少しコードを書くだけで簡単にメモリサイズを取得することができます。


(以下に記載した(サンプルコードの)実行結果は、全て64bitのJRE環境下でのものとなります)


java.SizeOf

■ツール(jar)の入手先

java.sizeOf project からダウンロードしてください

■主に使うAPI

Javaオブジェクトのメモリサイズを取得するためには基本的に以下を使用します

SizeOf#deepSizeOf

■サンプルコード

サンプルコードは以下の通りです。

import net.sourceforge.sizeof.SizeOf;

public class ArraySizeCheck {

    private static final int[] intArray1 = new int[] {1};
    private static final int[] intArray2 = new int[] {1, 2};
    private static final int[] intArray3 = new int[] {1, 2, 3};
    private static final int[] intArray4 = new int[] {1, 2, 3, 4};
    private static final int[] intArray5 = new int[] {1, 2, 3, 4, 5};
    private static final int[] intArray10 = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public static void main(String[] args) {
        SizeOf.skipFinalField(false);
        SizeOf.skipStaticField(true);
        SizeOf.setMinSizeToLog(1024);

        System.out.println("int[](size=1) size(byte) -> " + SizeOf.deepSizeOf(intArray1));
        System.out.println("int[](size=2) size(byte) -> " + SizeOf.deepSizeOf(intArray2));
        System.out.println("int[](size=3) size(byte) -> " + SizeOf.deepSizeOf(intArray3));
        System.out.println("int[](size=4) size(byte) -> " + SizeOf.deepSizeOf(intArray4));
        System.out.println("int[](size=5) size(byte) -> " + SizeOf.deepSizeOf(intArray5));
        System.out.println("int[](size=10) size(byte) -> " + SizeOf.deepSizeOf(intArray10));
    }
}

■実行時の注意

  • 実行時に、VM引数に -javaagent:{SizeOf.jar のパス} (例: -javaagent:./lib/SizeOf.jar)を指定する必要があります
  • 初期化処理として、コード中でSizeOf.skipFinalField(false)を実行する必要があります
  • 初期化処理として、コード中でSizeOf.skipStaticField(true)を実行する必要があります

■実行結果

JAVAGENT: call premain instrumentation for class SizeOf
int[](size=1) size(byte) -> 24
int[](size=2) size(byte) -> 24
int[](size=3) size(byte) -> 32
int[](size=4) size(byte) -> 32
int[](size=5) size(byte) -> 40
int[](size=10) size(byte) -> 56


Classmexer

■ツール(jar)の入手先

http://www.javamex.com/classmexer/ からダウンロードしてください

■主に使うAPI

Javaオブジェクトのメモリサイズを取得するためには基本的に以下を使用します

MemoryUtil#deepMemoryUsageOf

■サンプルコード

サンプルコードは以下の通りです。

import com.javamex.classmexer.MemoryUtil;

public class ArraySizeCheck {

    private static final int[] intArray1 = new int[] {1};
    private static final int[] intArray2 = new int[] {1, 2};
    private static final int[] intArray3 = new int[] {1, 2, 3};
    private static final int[] intArray4 = new int[] {1, 2, 3, 4};
    private static final int[] intArray5 = new int[] {1, 2, 3, 4, 5};
    private static final int[] intArray10 = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public static void main(String[] args) {
        System.out.println("int[](size=1) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray1));
        System.out.println("int[](size=2) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray2));
        System.out.println("int[](size=3) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray3));
        System.out.println("int[](size=4) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray4));
        System.out.println("int[](size=5) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray5));
        System.out.println("int[](size=10) size(byte) -> " + MemoryUtil.deepMemoryUsageOf(intArray10));
    }
}

■実行時の注意

実行する際に、VM引数に -javaagent:{classmexer.jar のパス} (例: -javaagent:./lib/classmexer.jar)を指定する必要があります

■実行結果

int[](size=1) size(byte) -> 24
int[](size=2) size(byte) -> 24
int[](size=3) size(byte) -> 32
int[](size=4) size(byte) -> 32
int[](size=5) size(byte) -> 40
int[](size=10) size(byte) -> 56


java-sizeof

名前から相当分かりにくいですが、先に紹介したjava.SizeOfとは別物です

■ツール(jar)の入手先

Maven Repository: com.carrotsearch » java-sizeof からダウンロードしてください

Mavenの場合はpom.xmlに以下を追記してください

<dependency>
    <groupId>com.carrotsearch</groupId>
    <artifactId>java-sizeof</artifactId>
    <version>{java-sizeof version}</version>
</dependency>

■主に使うAPI

Javaオブジェクトのメモリサイズを取得するためには基本的に以下を使用します

RamUsageEstimator#sizeOf

■サンプルコード

サンプルコードは以下の通りです。

import com.carrotsearch.sizeof.RamUsageEstimator;

public class ArraySizeCheck {

    private static final int[] intArray1 = new int[] {1};
    private static final int[] intArray2 = new int[] {1, 2};
    private static final int[] intArray3 = new int[] {1, 2, 3};
    private static final int[] intArray4 = new int[] {1, 2, 3, 4};
    private static final int[] intArray5 = new int[] {1, 2, 3, 4, 5};
    private static final int[] intArray10 = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public static void main(String[] args) {
        System.out.println("int[](size=1) size(byte) -> " + RamUsageEstimator.sizeOf(intArray1));
        System.out.println("int[](size=2) size(byte) -> " + RamUsageEstimator.sizeOf(intArray2));
        System.out.println("int[](size=3) size(byte) -> " + RamUsageEstimator.sizeOf(intArray3));
        System.out.println("int[](size=4) size(byte) -> " + RamUsageEstimator.sizeOf(intArray4));
        System.out.println("int[](size=5) size(byte) -> " + RamUsageEstimator.sizeOf(intArray5));
        System.out.println("int[](size=10) size(byte) -> " + RamUsageEstimator.sizeOf(intArray10));
    }
}

■実行結果

int[](size=1) size(byte) -> 24
int[](size=2) size(byte) -> 24
int[](size=3) size(byte) -> 32
int[](size=4) size(byte) -> 32
int[](size=5) size(byte) -> 40
int[](size=10) size(byte) -> 56


objectsize(Twitter Commons)

■ツール(jar)の入手先

Maven Repository: com.twitter.common » objectsize からダウンロードして下さい。

Mavenの場合はpom.xmlに以下を追記してください

<dependency>
    <groupId>com.twitter.common</groupId>
    <artifactId>objectsize</artifactId>
    <version>{objectsize-version}</version>
</dependency>

■主に使うAPI

Javaオブジェクトのメモリサイズを取得するためには基本的に以下を使用します

ObjectSizeCalculator#getObjectSize

■サンプルコード

サンプルコードは以下の通りです。

import com.twitter.common.objectsize.ObjectSizeCalculator;

public class ArraySizeCheck {

    private static final int[] intArray1 = new int[] {1};
    private static final int[] intArray2 = new int[] {1, 2};
    private static final int[] intArray3 = new int[] {1, 2, 3};
    private static final int[] intArray4 = new int[] {1, 2, 3, 4};
    private static final int[] intArray5 = new int[] {1, 2, 3, 4, 5};
    private static final int[] intArray10 = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public static void main(String[] args) {
        System.out.println("int[](size=1) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray1));
        System.out.println("int[](size=2) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray2));
        System.out.println("int[](size=3) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray3));
        System.out.println("int[](size=4) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray4));
        System.out.println("int[](size=5) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray5));
        System.out.println("int[](size=10) size(byte) -> " + ObjectSizeCalculator.getObjectSize(intArray10));
    }
}

■実行時の注意

objectsizeGuavaに依存しています。実行環境のclasspathにGuavaのjarが通っている必要があります

■実行結果

int[](size=1) size(byte) -> 24
int[](size=2) size(byte) -> 24
int[](size=3) size(byte) -> 32
int[](size=4) size(byte) -> 32
int[](size=5) size(byte) -> 40
int[](size=10) size(byte) -> 56


JOL

JOLはOpenJDKで提供されているツールです。本ツールの詳細については以下エントリを参照ください。




各ツールはJavaのバージョンによってサポートされていない場合があります。
Javaのバージョンごとの各ツールのサポート状況は以下の通りです。

Tool Java6 Java7 Java8
java.SizeOf
Classmexer
java-sizeof
objectsize(Twitter Commons) × ×
JOL ×