2013年3月19日火曜日

JavaのOutOfMemoryError Java heap spaceじゃない例

たまたまこういうエントリを見たので思い出したから書いてみます。先に書いとくと、このエントリ、「誰か教えて!」エントリです。
Javaでヒープ領域を余らせたままOutOfMemoryErrorを出す方法 - 西尾泰和のはてなダイアリー http://d.hatena.ne.jp/nishiohirokazu/20130319/1363672267
Thredを無限に作りまくるだけのコード。もっといい書き方があったら誰か教えてください。
import java.util.ArrayList;

public class Test  {

        public static void main(String[] args) {

                ArrayList hogeList = new ArrayList();
                while(true){
                        Hoge hoge = new Hoge();
                        hogeList.add(hoge);
                        hogeList.get(hogeList.size() - 1).start();
                        System.out.println(hogeList.size());
                }
        }
}
public class Hoge extends Thread {

        public void run() {
                String[] s = new String[1024*1024];
        }
}
これを実行するとOutOfMemory起きるんだけどJava heap spaceじゃなくてunable to create new native thread。

■t1.micro Amazon Linux 64bit
5531
5532
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:657)
        at Test.main(Test.java:14)
これはOSのメモリが足らない時に表示されます。Java仮想マシンのヒープが足らないって意味じゃないです。なのでヒープサイズ増やしたらなんとかなる種類のOufOfMemoryErrorではないです。 JavaのスレッドってOSの1プロセスに該当するからスレッド作りまくってOSのメモリ足らなくなったという状態なのでOSのメモリサイズ増やすと改善する。

上記の実行例Amazon EC2で試しました。インスタンスはt1.microだから613 MiB メモリです。5532個目のスレッドまでは作ることができています。
これを1.7 GiB メモリのm1.smallで動かしたらもっと動くんだぜドヤァってやろうと思ったらあれれ?m1.smallは5222個目のスレッドまでしか作れていませんね。
なんで???

■m1.small Amazon Linux 64bit
5217
5218
5219
5220
5221
5222
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:657)
        at Test.main(Test.java:14)
だれか教えて。
あとJavaのジェネリクスのをHTMLタグだと認識されてJavaコードの下に変な表示が。。。

0 件のコメント: