私のmacOSアプリケーションは重大なメモリリークを被ります。私はまだそれを理解していないが、多くのデバッグの後、私は原因を見つけたようだ。macOS:setNeedsDisplayInRectによるメモリ消費
このアプリケーションはピクセルを内部バッファに描画します。このピクセルは、NSView
サブクラスのdrawRect
メソッドで実際にスクリーンに描画されます。再ペイントは[self setNeedsDisplayInRect:rect]
によってトリガされます。
数時間後、プログラムは数ギガバイトのRAMを消費します。しかし、私が再描画したいときに、setNeedsDisplayInRect
という呼出しをループに入れて、言い換えると、1回だけではなく、1万回と言うと、メモリ消費は数分でギガバイトに上昇します。
メモリがdrawRect
メソッドで漏れていないことを確認するために、完全なボディを削除して空のメソッドのみを残しました。
ドキュメントからわかるように、setNeedsDisplayInRect
に与えられたすべての矩形は、再描画がイベントループの次の実行で実際に処理されるまで格納されます。だから私が10,000回呼び出すと、メモリ消費量はもっと高くなると予想されますが、それはいつも上昇し続けるとは思っていません。イベントループの1回の繰り返しの後に、格納されたすべてのrectをクリーンアップすると思います。
したがって、setNeedsDisplayInRect
を呼び出すと、メモリの容量が増加し続けているのはなぜですか?私は10,000回それを1秒間に何度も呼び出すことを知っていますが、まったく通常の使用ではありませんが、メモリー使用量は通常の状況でも上昇し続けます。
コードの抜粋:あなたは二次/バックグラウンドスレッドからこれを呼び出している場合
- (void)drawRect:(NSRect)dirtyRect {
// Currently, nothing happening
}
// My own method, that gets called from elsewhere.
- (void) drawToScreen:(int) x : (int) y : (int)w :(int)h :(int *)data
{
int rectYPos = MAX(height - y - h, 0);
NSRect rect = NSMakeRect(x, rectYPos, w, h);
for(int i = 0; i < 10000; i++)
{
[self setNeedsDisplayInRect:rect];
}
}
これは実際問題として発生しているようです。これはsetNeedsDisplay * docsには記載されていません。私は '{self setNeedsDisplayInRect:rect]'を 'dispatch_async(dispatch_get_main_queue()、^(void){[self setNeedsDisplayInRect:rect];});' ...に置き換え、メモリはもはやリークしません。つまり、それはまだゆっくりと上昇しますが、しばらくしてからは急に落ちます。繰り返す。 – Mathijs