08-20-2018 03:12 AM
Labviewで長期間連続でデータ測定と計算処理を行い、CSVファイルで保存するシステムを作っています。
「メモリがいっぱいです。」「~.viは、配列連結追加で停止しました。」というエラーメッセージが出てしまい、デバッグを行っています。
エラー原因としてフィードバックノードが絡む部分を疑っているのですが、フィードバックノードがメモリを扱うときの振る舞いが解らないので教えてください。
システムのフィードバックノードを使用している部分の概略を添付します。
このような使い方をした場合、メモリ上にストックされるデータが不要になった場合、いつ消去されるのでしょうか。あるいは残り続けてエラーの原因になるのでしょうか。
システム全体は、1~3日でエラーを起こして停止しています。
解決済! 解決策の投稿を見る。
08-20-2018 07:12 PM
Desktop Execution Trace Toolkitを使うと、メモリの取り扱いをログできるので見てみました。
以下は、添付されたVI内のWhileループをForループへ変更し、22回Forループを実行した結果です。
見ると、TRUEケースが実行されたのちレジスタへ空配列が渡されることにより、
該当するメモリが解放されているようです。
2回目の「Memory Allocate」では、配列連結追加関数が呼び出されることで再度メモリが確保されています。
その後TRUEケースが呼び出されて、メモリが解放されています。
ですから実装方法としては問題ないように見えるのですが、気になるのはメモリの再割り当てがどのように行われているかです。
今回は2回のメモリ割り当てが同じアドレスに対して行われましたが、長時間の実行だと、
異なるアドレスに割り当てられてしまう可能性もあるのではないでしょうか?
その場合メモリの断片化が起きて、いくらメモリを解放していてもメモリがオーバーフローとなってしまうのかなと思います。
いずれにせよ数日走らせるプログラムなのでしたら、ループの中で配列連結追加関数を使用し、
動的に配列サイズを変更していくことはお勧めできません。
こちらの「ループ内でのデータサイズ変更」を読んで、部分配列置換関数を使用するよう、
プログラムを変更されることをお勧めします。
08-20-2018 07:21 PM
検証ありがとうございます。
フィードバックノードがメモリ割り当てをどのようにやっているのかの文書が見つからず、疑ってしまいました。
うまく管理されていることが解りすっきりしました。
システムが停止する原因のバグは別の部分(ブロックダイアグラム上ではすぐ隣)で発見しました。これを修正してテストを続けます。
ありがとうございました。