Processingでメモリ不足
2009.6.5 金曜日
Processingは大きく分けて3つの描画方式(P2D、P3D、OpenGL)があって、今回はOpenGLで描画する際にフリーズする現象について報告。
Processing1.0.4(1.0.3でも同様)で、Windows XP SP3、Core2Quad 3GHz、GeForceGTS 250、RAM 4GB(3GB) と、MacOS 10.5.7、Core2Duo 2GHz、RadeonHD2400、RAM 2GB。
連番画像を読み込んで、パラパラ漫画の要領で表示しようとすると、あるデータ量でメモリ不足でフリーズ。エラーメッセージは「OutOfMemoryError」。だいたい30MB(6000x5000pixel)くらいのデータを使おうとした時で、Windows、Macどちらも同じ感じ。ファイルのデータ量ではなく解像度に依存しているみたいで、高圧縮JPEG、無圧縮PNGどちらでも同じ解像度のデータで起きる。
タスクマネージャやアクティビティモニタでは、メモリデルタとかフォルトが起きまくってメモリ使用量が急激に上がってしまう模様。下記プログラムの10行目の size() の第3引数を”P2D”や”P3D”にすると常識的なメモリ使用量で収まるし、問題なく動作するので”OPENGL”を使おうとした時のみの現象だと思う。
解決方法:パラパラ漫画みたいに同時に使用する画像が限られている場合は、数枚だけ先読みして、変数を使いまわしつつ、System.gc(); を使ってメモリ開放(ガベージコレクション)するとフリーズしない。一度に大量のテクスチャを使用するような状況では使えない方法だけど、上手くファイル管理できればそれなりの画像数は使えるみたい。あと、下記プログラムみたいに常にメモリ開放しながらだと実行速度(FPS)が遅いので、メモリーを監視しつつタイミング良く処理して下さい。
動作プログラムは下記。実行環境と同階層に「image」フォルダがあって、フォルダ内に「0 ~ 100.png」の画像ファイルがある状況で、4枚分の画像を先読み。
//Main.pde
import javax.media.opengl.*;
import processing.opengl.*;
int a = 0;
int b = 5;
PImage [] img = new PImage[b];
void setup() {
size(800, 600, OPENGL);
frameRate(100);
noSmooth();
for(int i = 0; i < b; i ++) {
String url = "image/" + str(i) + ".png";
img[i] = loadImage(url);
}
}
void draw() {
background(0);
image(img[a], 0, 0, img[a].width, img[a].height);
b++;
if (b == 100) {
b = 0;
}
String url = "image/" + str(b) + ".png";
img[a] = loadImage(url);
a ++;
if (a == 5) {
a = 0;
}
System.gc();
}
Posted by tmdf|OpenGL Processing