Java開発を行っているとOutOfMemoryErrorが発生し、ヒープサイズの拡張が必要になることが少なくありません。

本記事では、Javaのヒープサイズについての基礎知識から実際の設定方法についてご紹介していきます。

Javaのヒープサイズとは


Javaでは、プログラム実行時に生成されるオブジェクトのためのメモリ領域を「ヒープ領域」と呼び、その領域の大きさを「ヒープサイズ」と呼んでいます。

ヒープ領域の概要

JavaはJava Virtual Machine(JVM)と呼ばれる仮想マシン上で実行されますが、JVM上でプログラムが利用するメモリ領域として割り当てたものをヒープ領域と呼んでいます。

ヒープ領域は「New」と「Old」に分けられ、新たに作成されたオブジェクトや短期間だけ確保されるオブジェクト領域が「New」、寿命の長いオブジェクトが「Old」に該当します。

ヒープサイズの概要

ヒープサイズというのは、ヒープ領域の大きさで、「初期サイズ(-Xms)」と「最大サイズ(-Xmx)」を設定することが可能です。

ヒープサイズを大きくすることで、ガベージコレクションの回数を減らすことが出来るためパフォーマンスの向上に有効ですが、ヒープサイズを大きく設定しすぎるとリソースを無駄に消費したりする原因にもなってしまいます。

ヒープサイズとガベージコレクション

Javaでは、ガベージコレクションにより自動的にメモリ管理を行っているというのは知っている方も多いかと思いますが、このガベージコレクションが実行されるタイミングとしてヒープ領域がいっぱいになったタイミングがあげられます。

ヒープサイズを減らしているとすぐにヒープ領域がいっぱいになってしまい、ガベージコレクションの回数が増えてしまったり、メモリ不足でプログラムが強制終了してしまうことにも繋がるため、ヒープサイズの拡張を検討する必要が出てきます。

Javaのヒープサイズを確認してみよう


Javaのヒープサイズを確認する方法は複数存在しますが、今回はJava APIのRuntimeから取得する方法とコマンドからの起動オプションで取得する方法をご紹介していきます。

Javaプログラムで取得

Javaプログラムではサンプルのような記述でヒープサイズを取得することが出来ます。

public class Main {
	
	public static void main(String[] args) {
		
	    long total = Runtime.getRuntime().totalMemory();
	    long free = Runtime.getRuntime().freeMemory();
	    long max = Runtime.getRuntime().maxMemory();
	    System.out.println("total: " + total);
	    System.out.println("free: " + free);
	    System.out.println("max: " + max);
	}
}

実行した結果が下記です。

total: 136314880
free: 134346640
max: 2147483648

「totalMemory」で取得出来るのが「-Xms」で割り当てる初期サイズのヒープサイズを意味し、「freeMemory」はtotalMemoryから現在の使用領域を引いたサイズが表示されます。

つまりtotalMemoryからfreeMemoryを引いた値が、現在使用しているヒープサイズです。

また「maxMemory」では「-Xmx」にあたる最大サイズのヒープサイズが表示されます。

ポテパンダの一言メモ

ヒープサイズをKBで求めたい場合は「/1024」、MBで求めたい場合は「/(1024 * 1024)」で取得出来ます。

コマンドオプションで取得

次にjavaのコマンドオプションでヒープサイズを確認してみましょう。

$ java -XX:+PrintFlagsFinal -version | grep HeapSize 
一部抜粋
   size_t InitialHeapSize                          = 134217728                                 {product} {ergonomic}
   size_t MaxHeapSize                              = 2147483648                                {product} {ergonomic}
   size_t MinHeapSize                              = 8388608     
省略

Runtimeで取得した際と微妙に差はありますが、ほとんど同じ値が表示されていることを確認出来ます。

Javaの実行時にヒープサイズを指定する


Javaプログラム実行時にヒープサイズを指定する方法についても確認しておきたいましょう。

今回はコマンドから実行する方法とEclipse上で設定する方法についてご紹介していきます。

コマンド

コマンドからJavaプログラムを実行する場合、下記の形式でコマンドを実行します。

java -Xmsサイズ -Xmxサイズ クラス名

例えば「Sample1.java」クラスをメインとして、初期サイズ2MBの最大サイズ3MBで実行したい場合は下記の記述となります。

java -Xms2m -Xmx3m Sample1.java

Eclipse

Eclipseでの設定方法についても確認しておきましょう。


プロジェクトを右クリックして「実行」→「実行の構成」を選択します。


「Javaプロジェクト」から設定したいプロジェクトになっているかを確認します。


「引数」タブを選択し、「VM引数」のテキストエリアに「-Xms2m -Xmx3m」のように任意のヒープサイズを設定します。

テスト用サンプルコード

ヒープサイズの変化が分かるようにサンプルコードを用意しました。

public class Main {
	
	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder();
		int cnt = 0;
        while (true) {
            sb.append("10000000");
            cnt = cnt + 1;
            System.out.println(cnt + "回目のループ処理です。");
        }
	}
}

実行してみると筆者の環境では「-Xms2m -Xms3m」の設定で「36863回目」まで、「-Xms2m -Xms10m」の設定で「294911回目」まで処理が継続されるような差が生まれました。

さいごに: ヒープサイズを調整してJavaプログラムを実行しよう


本記事では、Javaにおけるヒープサイズの概要と実際に確認および設定する方法についてご紹介してきました。

ヒープサイズは少な過ぎず多過ぎずに調整するのが難しい部分でもありますが、アプリのパフォーマンスを最適化する上でも重要な役割を担います。

調整方法をきっちりと把握した上で、プログラムに最適なヒープサイズとなるようしっかりと調整を行いましょう。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。