実験プログラム
プログラムは、以下のようなサーブレットを作っただけ。
private static byte[][] data = new byte[100][]; private static int count = 0; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { // set content type resp.setContentType("text/plain"); // show memory usage resp.getWriter().printf("maxMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().maxMemory())); resp.getWriter().printf("totalMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().totalMemory())); resp.getWriter().printf("freeMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().freeMemory())); resp.getWriter().println(); // consume 10MB data[++count] = new byte[1024 * 10000]; resp.getWriter().println("count = " + count); resp.getWriter().println("size = " + (count * 10) + "MB"); resp.getWriter().println(); // show memory usage resp.getWriter().printf("maxMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().maxMemory())); resp.getWriter().printf("totalMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().totalMemory())); resp.getWriter().printf("freeMemory = %12s\n", new DecimalFormat().format(Runtime.getRuntime().freeMemory())); }
ローカルの開発環境で実行
ローカル環境での初回アクセス時の表示。
maxMemory = 518,979,584 totalMemory = 16,252,928 freeMemory = 11,581,272 count = 1 size = 10MB maxMemory = 518,979,584 totalMemory = 26,562,560 freeMemory = 11,861,168
16,252,928 - 11,581,272 = 4,671,656 ということで、初期のヒープ使用量は約5MB。
ローカル環境では、以下の表示まで正常に動作。
maxMemory = 518,979,584 totalMemory = 518,979,584 freeMemory = 31,941,032 count = 48 size = 480MB maxMemory = 518,979,584 totalMemory = 518,979,584 freeMemory = 21,701,016
次のアクセスで次のようなエラーが表示された。
java.lang.OutOfMemoryError: Java heap space
App Engine 環境で実行
App Engine 環境での初回アクセス時の表示。
maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 113,263,432 count = 1 size = 10MB maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 103,023,416
freeMemory が maxMemory より大きいという意味のわからない表示になった。
freeMemory の減少は 113,263,432 - 103,023,416 = 10240016 で、ほぼ10MBの減少。
App Engine 環境での二回目のアクセス時の表示。
maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 102,853,368 count = 2 size = 20MB maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 92,613,352
予想通りの動作。
App Engine 環境では、以下の表示まで正常に動作。
maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 20,286,944 count = 10 size = 100MB maxMemory = 104,857,600 totalMemory = 104,857,600 freeMemory = 10,046,928
次のアクセスで次のようなエラーが表示された。
Error: Server Error The server encountered an error and could not complete your request. If the problem persists, please report your problem and mention this error message and the query that caused it.
ということで、100MBは使えそうです。
100MBという数値は google で検索かけるといろんなところに出てくるので、信頼性は高いですね。
しかし、オフィシャルな情報としてどこかに公開されているのでしょうか??
まとめ
Google App Engine / Java のヒープメモリについて
- 開発環境のヒープメモリの上限は約500MB
- App Engine 環境のヒープメモリの上限は約100MB
- 開発環境とApp Engine 環境のヒープメモリ上限のギャップを把握しておかないと、App Engine 環境だけで OutOfMemory で泣く可能性があるので注意!
0 件のコメント:
コメントを投稿