You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
plotの内容を更新する方法
19 views (last 30 days)
Show older comments
koji fukumoto
on 31 Aug 2020
お世話になります。
plot関数でグラフ上(Axesオブジェクト上)に複数の点を描画し、
plot関数の戻り値のオブジェクトに対してset関数を用いて点の位置('XData'及び'YData')を更新するプログラムを作成しましたが、
起動後、しばらくするとタスクマネージャ上のメモリ使用量が増加していきます。
基本的な質問で申し訳ありませんが、plot関数で描画した点の位置を変える方法として、上記実装は適切でしょうか?
(適切でない為、メモリリーク?が発生しているのではないかと考えております)
※本来ならサンプルコードを提示すべきところですが、提示できる形に整形するのに時間が掛かる為、取り急ぎ上記のような質問をさせて頂きました。
よろしくお願い致します。
Answers (1)
michio
on 1 Sep 2020
> plot関数の戻り値のオブジェクトに対してset関数を用いて点の位置('XData'及び'YData')
R2014b 以降は set を使わず h.XData = [] という風に(h が戻り値のオブジェクト)プロパティを変える方法がオススメではありますが、描画後の点の位置を変える方法としてはスタンダードで適切な方法であると思います。メモリ使用量が増加する直接の原因とは考えにくいと思いますが、、他に何か要因があるのかもしれません。
21 Comments
koji fukumoto
on 1 Sep 2020
ご回答ありがとうございます。
方法として何ら不適切ではない旨、承知致しました。
メモリ使用量増加の調査として、whos関数を用いて
・メモリ使用量が増加する前
・メモリ使用量が増加した後
の各変数のサイズを確認してみたのですが、特に大きな変化はありませんでした。
(後者において、ある変数のサイズが増えていていることを期待しておりました)
他に何か調査につかえる関数やツールなどございましたらご教示頂けないでしょうか。
よろしくお願い致します。
michio
on 1 Sep 2020
ぱっと思いつくところですと、
a = 1;
for N = 1:100
a = [a,N];
end
というように同じ変数名で、配列サイズが動的に異なるようなコードになっていないか・・という点です必ずしもこれがご提示の現象を引き起こすとは限りません。
> メモリリーク?が発生しているのではないかと考えております
これがどこで発生してしまっているのか・・再現コードを頂けますと、開発チームにも調査してもらうこともできますので、是非ご検討ください。
koji fukumoto
on 11 Sep 2020
提示頂いたコードで確認しても、問題はありませんでした。
また、再現コードの提供に関しては、機密情報を含める為すぐに切り出すことが難しいです。
一点確認させてください。
プログラムに何ら問題が無かったとしても、UDP受信⇒グラフ表示、をし続けるプログラムを延々動かした場合、MATLAB使用メモリは必然的に増えていくものですか?
例えば、動作ログ情報を内部的に蓄積していくために使用メモリが増える使用である、など・・・。
(グラフ描画を抑止したコードでも、使用メモリが増え続けていることを確認したので)
もしそうである場合、使用メモリが増え続ける事に対して何らかの対策も存在しているのでしょうか?
例えば、メモリ使用率が一定の値に達すると、キャッシュの解放等を行う仕組みが実装されている、など・・・。
よろしくお願い致します。
koji fukumoto
on 15 Sep 2020
ご返信ありがとうございます。
はい。File Exchange のjudp(A simple UDP communications application)を用いて実装しております。
michio
on 15 Sep 2020
今でも一定数 download 数がありますしコメントも多いですが、メモリに関するコメントは見られませんでした。あくまで可能性の 1 つですが、もしこの実装に由来する現象である場合には制作者に問い合わせる(File Exchange のコメント欄)のが一番の近道になってしまいます。申し訳ございません。
> 例えば、メモリ使用率が一定の値に達すると、キャッシュの解放等を行う仕組みが実装されている
という点に関しては少なくとも製品外のものに由来する場合はそういった仕組みは組み込まれている可能性は低いと見ています。
koji fukumoto
on 23 Sep 2020
本件(使用メモリ増加の件)に関しまして、別視点からの質問をさせてください。
増加している使用メモリは、ガベージコレクションのタイミングで減少するのかもしれないと思ったのですが、MATLABの「ガベージコレクション実行契機」がよくわかりませんでした。
①MATLABでガベージコレクションが実行される契機はどのようなタイミングでしょうか?
②手動でガベージコレクションを実行する方法はありますか?
の2点に関しまして、お手数ですがご回答頂けますでしょうか。
よろしくお願い致します。
koji fukumoto
on 25 Sep 2020
GCに関する情報展開ありがとうございます。
URLの内容については精査中ですが、新たに分かったことがございますので展開させて頂きます。
----------------------------------------------------------------------
当該プログラムを実行中、ハンドル数がすごい勢いで増加していることが分かりました。
(ハンドル数の増加はタスクマネージャのパフォーマンスタブ「ハンドル数」にて確認)
同時に、当該プログラムの「グラフ描画をOFF」にして実行すると、ハンドル数は増加しませんでした。
当該プログラムで行っている「グラフ描画」は、
①UDP受診した600個の点の位置情報を解析
②scatter関数の戻り値のハンドルが有効なら、delete関数で点を消去してハンドルを解放
③scatter関数を用いて600個の点を描画
④次のフレームへ(①へ戻る)
という処理を、50ms毎に実行するものです。
増加するハンドル=scatter関数の戻り値のハンドル だと思っているのですが、上記のように必ずdeleteしているのでハンドルリークは起こっていない認識です。
先頭フレーム以外は、②でdeleteが実行されていることを確認済みです。
----------------------------------------------------------------------
scatter関数の戻り値のハンドルの解放処理として、何か抜けている点などございますでしょうか?
よろしくお願い致します。
michio
on 25 Sep 2020
Edited: michio
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
ご提示頂いたコードを実行しても、ハンドル数は増えませんでした。
しかし、このコードのままだと実際にグラフが表示されることが無い為、
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);
pause(0.01);
end
というように「pause」を掛けてあげると、ハンドル数が増加していきます。
(実際に当該プログラムにおいても、「グラフ再描画の為&50ms周期をキープする為」にpauseを実行しております)
MATLAB的に、これは当然の現象なのでしょうか?
よろしくお願い致します。
michio
on 25 Sep 2020
Edited: michio
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
■ver情報
>> ver
---------------------------------------------------------------------------------------------------
MATLAB バージョン: 9.7.0.1319299 (R2019b) Update 5
MATLAB ライセンス番号: XXXXXXXX
オペレーティング システム: Microsoft Windows 10 Home Version 10.0 (Build 18363)
Java バージョン: Java 1.8.0_202-b08 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
---------------------------------------------------------------------------------------------------
MATLAB バージョン 9.7 (R2019b)
DSP System Toolbox バージョン 9.9 (R2019b)
Phased Array System Toolbox バージョン 4.2 (R2019b)
Signal Processing Toolbox バージョン 8.3 (R2019b)
■「y を変化させて、pause をかけてみましたが~」のコードについて
提示頂いたコードを実行しても、私の環境ではハンドルは増加しませんでしたが、
・pauseの引数を「0.05」から「0.01」に変更して実行
・実行中(グラフ表示中)に、マウスカーソルをグラフの上に乗せる
と、ハンドル数が増加します。
(pause引数が0.05の場合は、グラフ上にマウスカーソルを載せてもハンドル数は増加しませんでした)
更に、pause引数を「0.001」にすると、マウスカーソルをグラフ上に乗せなくてもハンドル数が増加します。
■opengl
>> opengl software
>> opengl info
Version: '1.1.0'
Vendor: 'Microsoft Corporation'
Renderer: 'GDI Generic'
MaxTextureSize: 1024
Visual: 'ビジュアル 0x48、(RGB 24 ビット (8 8 8)、Z 深度 16 ビット、ソフトウェア、シングル バッファー、アンチエイリアス 0 サンプル)'
Software: 'true'
HardwareSupportLevel: 'none'
SupportsGraphicsSmoothing: 0
SupportsDepthPeelTransparency: 0
SupportsAlignVertexCenters: 0
Extensions: {3×1 cell}
MaxFrameBufferSize: 0
上記実行後、pause(0.001) で実行しましたが、ハンドル数は増加しました。
※念の為、現象再現している当方のPCスペックを開示しておきます。
・CPU:Core i7-7500U CPU @ 2.70GHz
・メモリ:DDR4-16GB
・ストレージ:SSD 128GB、HDD 1TB
・NVIDIA® GeForce® 940MX グラフィックス 4GB
よろしくお願い致します。
koji fukumoto
on 1 Oct 2020
michio様、
pauseを用いるとハンドル数が増える件に関しまして、ご回答の程よろしくお願い致します。
michio
on 1 Oct 2020
イベントでバタバタしておりご連絡が遅くなり申し訳ございません。
R2019b にて pause(0.01) にすることでハンドル数の増加が確認できております。ありがとうございます。社内で確認を取っておりますので、ハンドル数の増加との関係について分かり次第ご連絡いたします。
また、メモリ使用量は増えていないということで間違いないでしょうか。
参考までですが、R2020b で試したところ pause(0.001) でもハンドル数の増加は見られませんでした。
koji fukumoto
on 1 Oct 2020
大変お忙しいところ恐れ入ります。
> また、メモリ使用量は増えていないということで間違いないでしょうか。
いいえ、ハンドル数の増加とメモリの増加は関連があるようです。
(ハンドル数が増えると、使用メモリも増加しております)
> 参考までですが、R2020b で試したところ pause(0.001) でもハンドル数の増加は見られませんでした。
諸々の関係で、まずはR2019bでの解決を目指したいです。
どうしても無理な場合は、R2020bへのバージョンアップも検討致します。
尚、グラフ描画の為にpauseではなくdrawnowを使う方法もあるのですが、pauseよりも処理速度が劣るのか、drawnowだとUDP受信の周期に処理が間に合わなくなり、フレーム抜けが発生しやすくなるので問題があります。
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
> UDP 受信など関係なく(例えば上のコードでも)ハンドル数の増化とメモリの増加が同時に発生しているということでしょうか?
はい。
上記の提示くださったコードを実行すると「ハンドル数」「使用メモリ」共に増加しております。
(使用メモリに関しては、起動後10数秒は変化ありませんが、動かし続けていると増加しております)
koji fukumoto
on 2 Oct 2020
2020bをインストールして、提示してくださったコードを実行してみました。
たしかに、ハンドル数の増加は見られませんでしたが、使用メモリは増加していっております。
以上、取り急ぎ情報展開まで。
>R2019b にて pause(0.01) にすることでハンドル数の増加が確認できております。ありがとうございます。社内で確認を取っておりますので、ハンドル数の増加との関係について分かり次第ご連絡いたします。
引き続き、上記の確認結果のご連絡をお待ちしております。
よろしくお願い致します。
koji fukumoto
on 9 Oct 2020
michio様、
>R2019b にて pause(0.01) にすることでハンドル数の増加が確認できております。ありがとうございます。社内で確認を取っておりますので、ハンドル数の増加との関係について分かり次第ご連絡いたします
上記、どのような状況でしょうか?
お手数ですがご返信の程よろしくお願い致します。
MATLAB Answers ではなく、正式にサービスリクエストを作成した方がよい場合はその旨ご連絡ください。
よろしくお願い致します。
michio
on 11 Oct 2020
Edited: michio
on 11 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 受信処理側の事情もあると想像します。
描画処理を高速化する・・という選択肢に関して、現時点でソフト側でできることで思いつくのは描画データ点数を減らすか、マーカー '.' の使用(最も単純で速いという話を聞いたことがあります)でしょうか・・。
いかがでしょうか?
See Also
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!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)