2012-05-09 17 views
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 
+0

サンプルコードを投稿できますか? –

+0

本番環境でもこの問題がありますか? – proppy

+0

本番環境では問題ありません。 – Fabien

答えて

1

。スケーラビリティはそれの第一の関心事ではありません。ファイルをメモリにキャッシュするのは間違いありません。これはどのように動作するはずです。

関連する問題