GAE/Jの実験(heapサイズ)
GAE/J のHeapサイズの上限を実際に測ってみたくて、実験してみた。
実験プログラム
プログラムは、以下のようなサーブレットを作っただけ。
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,272count = 1
size = 10MBmaxMemory = 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,032count = 48
size = 480MBmaxMemory = 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,432count = 1
size = 10MBmaxMemory = 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,368count = 2
size = 20MBmaxMemory = 104,857,600
totalMemory = 104,857,600
freeMemory = 92,613,352
予想通りの動作。
App Engine 環境では、以下の表示まで正常に動作。
maxMemory = 104,857,600
totalMemory = 104,857,600
freeMemory = 20,286,944count = 10
size = 100MBmaxMemory = 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 で泣く可能性があるので注意!