1
開発サーバー上で、FileService APIを使用して単一のファイルにデータを書き込もうとしています。
少量のデータを書き込んでも、ファイルを閉じると(close()
)、メモリは解放されません。 closeFinally()
からFileService
まではメモリを解放する必要があります。したがって、私は、closeFinally()
が呼び出されるまで、ファイル全体がメモリにキャッシュされていると考えています。これは、単一のBLOBに巨大なファイルを書きたい場合、いくつかの問題を引き起こす可能性があります。
このメモリの問題を解決する方法はありますか?ここで FileServiceで大容量のファイルがメモリ不足になる
String veryLongString = "verryyyyllooooonnnnggggssssttttrrrriiiiinnnnnggggg";
for (int i = 0; i < 10; ++i) {
veryLongString += veryLongString;
}
// veryLongString.length() => 51200 char
FileService FILESERVICE =
FileServiceFactory.getFileService();
// Create new file
String newPath =
FILESERVICE.createNewBlobFile("application/octet-stream").getFullPath();
for (int i = 0; i < 10; ++i) {
System.out.println(i);
// Open file for append
AppEngineFile file = new AppEngineFile(newPath);
FileWriteChannel writeChannel = FILESERVICE.openWriteChannel(file, true);
OutputStream out = Channels.newOutputStream(writeChannel);
// Append some data to this file
for (int j = 0; j < 5000; ++j) {
out.write(veryLongString.getBytes());
}
writeChannel.close();
// Writed 5000*51200 => 256Mo char (to memory, should be
// also persisted to disk)
}
// Writed all data we want, we finally close the file
AppEngineFile file = new AppEngineFile(newPath);
FileWriteChannel writeChannel = FILESERVICE.openWriteChannel(file, true);
writeChannel.closeFinally();
出力:開発サーバーを使用して、アプリケーションをテストとデバッグに役立つように設計されて
0
1
2
3
com.google.apphosting.api.ApiProxy$UnknownException: An error occurred for the API request file.Append().
at com.google.appengine.tools.development.ApiProxyLocalImpl$AsyncApiCall.callInternal(ApiProxyLocalImpl.java:518)
at com.google.appengine.tools.development.ApiProxyLocalImpl$AsyncApiCall.call(ApiProxyLocalImpl.java:452)
at com.google.appengine.tools.development.ApiProxyLocalImpl$AsyncApiCall.call(ApiProxyLocalImpl.java:430)
at java.util.concurrent.Executors$PrivilegedCallable$1.run(Executors.java:463)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.concurrent.Executors$PrivilegedCallable.call(Executors.java:460)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at java.io.OutputStream.write(OutputStream.java:58)
at com.google.appengine.api.files.dev.FileMetadata.append(FileMetadata.java:198)
at com.google.appengine.api.files.dev.LocalFileService.append(LocalFileService.java:357)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.appengine.tools.development.ApiProxyLocalImpl$AsyncApiCall.callInternal(ApiProxyLocalImpl.java:498)
... 10 more
サンプルコードを投稿できますか? –
本番環境でもこの問題がありますか? – proppy
本番環境では問題ありません。 – Fabien