HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

File.createTempFile() と File.deleteOnExit() のコンボ罠の続き

昨日書いたエントリの続き。

File.createTempFile() と File.deleteOnExit() のコンボ罠 - HHeLiBeXの日記 正道編

「再現はできていない」と書いたが、目指していたものがLinux環境でのJava VMのクラッシュ(hs_err_xxxx.log を吐く状態)だったためで、メモリが増え続けてるぞということを確認するだけなら再現はできているといえる。

【!!注意!!】以下のコードを実行するときは、OSごと落ちても大丈夫な状態にしておいたほうが安心。

DeleteOnExitTest.java の内容。

import java.io.File;

public class DeleteOnExitTest {
    public static void main(String[] args) {
        try {
            File test = File.createTempFile("test",".txt");
            for (long i = 0; true; ++i) {
                if (i % 100 == 0) {
                    if (i % 100000 == 0) {
                        System.out.println("--- " + i + " ---");
                    }
                    Thread.sleep(10);
                }
                test.deleteOnExit();
            }
        } catch (Exception e){e.printStackTrace();} 
    }
}

いつもの「Windows Vista Business on Let's Note CF-W5」上のMinGW/MSYSから起動したときのコマンドログ。

$ java -version
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) Client VM (build 1.5.0_22-b03, mixed mode, sharing)
$ javac DeleteOnExitTest.java
$ java DeleteOnExitTest.java
--- 0 ---
--- 100000 ---
    :
--- 7200000 ---
--- 7300000 ---
--- 7400000 ---
Exception in thread "main" java.lang.OutOfMemoryError
        at java.io.WinNTFileSystem.deleteOnExit(Native Method)
        at java.io.File.deleteOnExit(File.java:903)
        at DeleteOnExitTest.main(DeleteOnExitTest.java:14)
(Ctrl-C)

途中で、「メモリが足りません。終了しますか?」みたいなダイアログが出てくるが、[キャンセル]をクリックして無視。
最後はどうにもならなくなってCtrl-Cで強制終了した。
Ctrl-Cする直前のタスクマネージャでの表示。

Process Explorer*1でメモリが増える状況を監視していたのだが、耐え切れずにProcess Explorerが停止してしまったという‥
また、起動していたFirefoxもいつの間にかいなくなっていたり‥
とりあえず、再度取り直したProcess Explorerの画面をば。(取り直したので、前掲のタスクマネージャの表示とはプロセスIDが異なる。)

メモリ使用量が、感動するほどに線形に増えている。この増えているメモリはヒープメモリではない。SunのJava VMを使っているので、ヒープの最大サイズは64MBになっているはずだから。

最後は1GB程度で頭打ちになった。

    • -

ちなみに、VMWare上のUbuntu 8.04でも試したのだが、以下のような感じの終わり方をする。(こっちは確か Java 2 SDK, SE 1.4.2_12)

$ java DeleteOnExitTest.java
    :
--- 7800000 ---
--- 7900000 ---
--- 8000000 ---
Killed
$ 

OSが危険を察知して停止するのだろうか。

*1:Process Explorer。旧Sysinternalsで公開されていたものだと思う