fastqc memory error – java実行時により大きなメモリを割り当てる方法

bamファイルに対してfastqcを実行したら、メモリが足りないというエラーが発生しました。実行環境は十分にメモリーを積んでいたので、fastqc実行時のjavaのメモリーオプションを強制的に書き換えて実行したら、正常終了しました。

fastqc – OutOfMemoryError 解決方法

エラー内容

bamファイル(約20GB)に、fastqcを実行したとき、下記のようなエラーが発生しました。最初は、「java.lang.OutOfMemoryError: GC overhead limit exceeded」、次に、「java.lang.OutOfMemoryError: Java heap space」と表示されました。結局は、「Java heap space」のエラーと理解して、対策をとることにしました。

$ fastqc *.bam
Started analysis of mydata.bam # 約20G

Exception in thread "Thread-1" java.lang.OutOfMemoryError: GC overhead limit exceeded

Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space

エラー原因

実行環境は十分なメモリーを積んでいたので、javaの実行時にオプションでメモリーの制限があるのかもしれないと考えました。

Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space 原因: 詳細メッセージのJavaヒープ領域は、Javaヒープにオブジェクトを割り当てることができなかったことを示しています。このエラーは、必ずしもメモリー・リークを意味しません。この問題は、指定されたヒープ・サイズ(指定されていない場合はデフォルト・サイズ)がアプリケーションにとって十分でないという、単純な構成の問題である可能性があります。

Java Platform, Standard Editionトラブルシューティング・ガイド – 3.2 OutOfMemoryError例外の理解

javaのメモリーオプション

fastqcのコールシーケンスを確認してみましょう。対象となるファイルは、/Path_to_Fastqc/fastqcです。

ファイルをエディタで開いてみてみましょう。間違って編集してしまわないように、readonly(読み取り専用)で開くと安心です。

「$java_bin,@java_args」の部分が、実際のjavaの呼び出しです。@java_argsに実行時に指定されたオプションが格納されています。@files以降はfastqcの対象となるファイルです。

# fastqc 150行目付近

if ($java_bin ne 'java') {
	system $java_bin,@java_args, "uk.ac.babraham.FastQC.FastQCApplication", @files;
}
else {
	exec $java_bin,@java_args, "uk.ac.babraham.FastQC.FastQCApplication", @files;
}

__DATA__

@java_argsには、判断された様々な条件に対応したオプションが書き込まれています。

# fastqc 90行目付近

if ($threads) {
	if ($threads < 1) {
		die "Number of threads must be a positive integer";
	}
	
	push @java_args ,"-Dfastqc.threads=$threads";
	my $memory = 250 * $threads;
	unshift @java_args,"-Xmx${memory}m";
}
else {
	unshift @java_args,'-Xmx250m';
}

メモリーに関するオプションに注目します。

@java_args,’-Xmx250m’部分(スレッド非対応)、または、@java_args,”-Xmx${memory}m”部分(スレッド対応)が、javaの実行時にメモリの上限を決めている部分です。

今回は、約60GBのメモリーを準備していたので、@java_args,’-Xmx30000m’と書き換えて実行しました(直接書き換えるより、コメント機能をうまく利用する方が簡単に戻せて良いです)。初期サイズ・最大サイズで指定できるのですが、今回は最大サイズの変更だけで正常に動作しました。

確認できたら、ファイルを元に戻すのを忘れないように!

直接ファイルを書き換えなくても、$ java -Xmx250m -classpath …と、直接オプションを渡せられるかもしれません。また、該当オプションを削除するだけで良かったかもしれません(オプションを指定しない場合、実行環境のメモリーを適当に割り当ててくれる)。機会があれば、いろいろ試してみたいと思います。