plotの内容を更新する方法
Show older comments
お世話になります。
plot関数でグラフ上(Axesオブジェクト上)に複数の点を描画し、
plot関数の戻り値のオブジェクトに対してset関数を用いて点の位置('XData'及び'YData')を更新するプログラムを作成しましたが、
起動後、しばらくするとタスクマネージャ上のメモリ使用量が増加していきます。
基本的な質問で申し訳ありませんが、plot関数で描画した点の位置を変える方法として、上記実装は適切でしょうか?
(適切でない為、メモリリーク?が発生しているのではないかと考えております)
※本来ならサンプルコードを提示すべきところですが、提示できる形に整形するのに時間が掛かる為、取り急ぎ上記のような質問をさせて頂きました。
よろしくお願い致します。
Answers (1)
michio
on 1 Sep 2020
0 votes
> plot関数の戻り値のオブジェクトに対してset関数を用いて点の位置('XData'及び'YData')
R2014b 以降は set を使わず h.XData = [] という風に(h が戻り値のオブジェクト)プロパティを変える方法がオススメではありますが、描画後の点の位置を変える方法としてはスタンダードで適切な方法であると思います。メモリ使用量が増加する直接の原因とは考えにくいと思いますが、、他に何か要因があるのかもしれません。
21 Comments
koji fukumoto
on 1 Sep 2020
michio
on 1 Sep 2020
ぱっと思いつくところですと、
a = 1;
for N = 1:100
a = [a,N];
end
というように同じ変数名で、配列サイズが動的に異なるようなコードになっていないか・・という点です必ずしもこれがご提示の現象を引き起こすとは限りません。
> メモリリーク?が発生しているのではないかと考えております
これがどこで発生してしまっているのか・・再現コードを頂けますと、開発チームにも調査してもらうこともできますので、是非ご検討ください。
koji fukumoto
on 11 Sep 2020
michio
on 15 Sep 2020
ご連絡が遅くなり申し訳ございません。
UDP 受信を続けた場合でも本来であれば使用メモリが増え続ける・・というのは考えにくいですね。。以前のご質問を拝見したのですが、今回は File Exchange のツールを使用して UDP 通信をされていらっしゃいますでしょうか?
koji fukumoto
on 15 Sep 2020
michio
on 15 Sep 2020
今でも一定数 download 数がありますしコメントも多いですが、メモリに関するコメントは見られませんでした。あくまで可能性の 1 つですが、もしこの実装に由来する現象である場合には制作者に問い合わせる(File Exchange のコメント欄)のが一番の近道になってしまいます。申し訳ございません。
> 例えば、メモリ使用率が一定の値に達すると、キャッシュの解放等を行う仕組みが実装されている
という点に関しては少なくとも製品外のものに由来する場合はそういった仕組みは組み込まれている可能性は低いと見ています。
koji fukumoto
on 23 Sep 2020
michio
on 24 Sep 2020
ドキュメンテーションページにて記載が見つからないため詳細は非公開と解釈しておりますが、以下に参考になりそうな外部ページを紹介だけ致します。
koji fukumoto
on 25 Sep 2020
ご連絡ありがとうございます。ハンドルの delete 自体は無いはずですね・・。
R2019b にて以下のコードを試してみましたが、ハンドル数が増加している様子はこちらの環境では確認できませんでしたが、fukumoto 様の環境ではいかがでしょうか?
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
sz = linspace(1,100,200);
s = scatter(x,y,sz)
for ii=1:1e5
delete(s)
s = scatter(x,y,sz);
end
koji fukumoto
on 25 Sep 2020
違いが分かりやすいように y を変化させて、pause をかけてみましたが、こちらの環境ではハンドル数の増加は見られませんでした。
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
sz = linspace(1,100,200);
s = scatter(x,y,sz)
for ii=1:1e5
delete(s)
y = cos(x) + rand(1,200);
s = scatter(x,y,sz);
% drawnow
pause(0.05)
end
ちなみに試したバージョンと環境は以下の通りです。同じ R2019b でも Update 5 なのでこの違いはあるかもしれません。
>> ver
---------------------------------------------------------------------------------------------------
MATLAB バージョン: 9.7.0.1319299 (R2019b) Update 5
MATLAB ライセンス番号: xxxxxxxxxx
オペレーティング システム: Microsoft Windows 10 Enterprise Version 10.0 (Build 18362)
Java バージョン: Java 1.8.0_202-b08 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
---------------------------------------------------------------------------------------------------
またグラフィックボードの影響かどうかをチェックするために opengl software とハードを使わない形で描画も試してみて変化があるかを確認頂けますか?
>> opengl software
>> opengl info
Version: '1.1.0'
Vendor: 'Microsoft Corporation'
Renderer: 'GDI Generic'
MaxTextureSize: 1024
Visual: 'ビジュアル 0x4d、(RGB 24 ビット (8 8 8)、Z 深度 16 ビット、ソフトウェア、シングル バッファー、アンチエイリアス 0 サンプル)'
Software: 'true'
HardwareSupportLevel: 'none'
SupportsGraphicsSmoothing: 0
SupportsDepthPeelTransparency: 0
SupportsAlignVertexCenters: 0
Extensions: {3×1 cell}
MaxFrameBufferSize: 0
koji fukumoto
on 28 Sep 2020
Edited: koji fukumoto
on 28 Sep 2020
koji fukumoto
on 1 Oct 2020
michio
on 1 Oct 2020
イベントでバタバタしておりご連絡が遅くなり申し訳ございません。
R2019b にて pause(0.01) にすることでハンドル数の増加が確認できております。ありがとうございます。社内で確認を取っておりますので、ハンドル数の増加との関係について分かり次第ご連絡いたします。
また、メモリ使用量は増えていないということで間違いないでしょうか。
参考までですが、R2020b で試したところ pause(0.001) でもハンドル数の増加は見られませんでした。
koji fukumoto
on 1 Oct 2020
michio
on 1 Oct 2020
何度も細かいところで申し訳ございません。。
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
sz = linspace(1,100,200);
s = scatter(x,y,sz)
for ii=1:1e5
delete(s)
y = cos(x) + rand(1,200);
s = scatter(x,y,sz);
pause(0.001)
end
UDP 受信など関係なく(例えば上のコードでも)ハンドル数の増化とメモリの増加が同時に発生しているということでしょうか?当方の R2019b Update 5 で試したところハンドル数は増加したもののメモリの顕著な増加は盛られなかったため確認させていただきました。
koji fukumoto
on 1 Oct 2020
koji fukumoto
on 2 Oct 2020
koji fukumoto
on 9 Oct 2020
お待たせしており申し訳ございません。
Task Manager 上のハンドル (MS Windows GDI Handles) 数の MATLAB 側の処理内容に対応する内容については確認ができておりませんが、開発サイドのひとまずの見解としては
pause(0.01) is attempting to queue 100 frames per second and the machine is not drawing 100 frames per second, so there is a backlog of frames that appears as a memory leak.
とのことで、PC が処理できる以上の描画命令が溜まりメモリ使用量増加に表れている。すなわち単純に pause(0.01) で指定したレートでグラフ描画ができていないという
ことになりますが、この点については現象と合致しますでしょうか?
今回フレーム抜けが発生するために pause で UDP 受信の処理に合わせているとのこと。
描画処理が間に合っていないという点について、例えばフレーム抜けを許容しながら処理を追いつかせるのであれば
drawnow limitrate
の使用がお勧めです。ただ、UDP 受信処理側の事情もあると想像します。
描画処理を高速化する・・という選択肢に関して、現時点でソフト側でできることで思いつくのは描画データ点数を減らすか、マーカー '.' の使用(最も単純で速いという話を聞いたことがあります)でしょうか・・。
いかがでしょうか?
Categories
Find more on グラフィックス パフォーマンス in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!