グラフの件の案を出しましたが、
まず、
>データ数が変わらくなったのは、処理内容が多すぎてタイマーイベントに追いついてい
>けてなかったからでしょうか。
これを解決しないとまずいですね。
グラフ処理を止めて、タイマー時間を増やしていくとどうなりますか?
>1時間半経ってもデータ数は変わらなくなりました。
>ただ、やはりメモリは、少しづつ増えて行ってます。
これはどうなりますか?
ITOさん みいさん ありがとうございます。
グラフ処理をコメントアウトして、タイマー時間100msを200ms、400msにしていくとどうなるか
を試して見ます。
あとグラフの表示する方法として、どうしてもリアルタイムに見えるように、数値表示に追従す
るような形で描画する場合、AddXY()関数は使用メモリをどんどん増やしていくとありました
が、10分程度であればデータ数のも減少しないでいけると思いますので、5分に1回の割合でメモ
リのリフレッシュは出来ないでしょうか。
グラフの描画には何を使用されていますか。
Chartコントロールだったら
http://ar4pro.exblog.jp/tags/C%23/
C#だけど、少し参考になるかも
Addしたポイントデータはグラフ内部で保持されていると
思われますので、不要なポイントを削除していかないと
いけないと思います。
全クリアしかないのであれば、描画用のデータ領域用意して
そこにデータセットしておいて、フルスケールになったら
一旦全クリアしてその領域からデータセットし直すとか。
ただしAddXYの度に描画イベントがはしるからセットしている
間描画を止めないととかちらつきとかいろいろ出てくるかも。
むか~し自力描画してた時は1ピクセル分ビットマップを
横にずらして1ピクセル分描画してました(^^;)
みいさん ITOさん ありがとうございます。
グラフ描画を1000ポイントごとにでクリア(chart1->Series[0]->Points->Clear();)す
ることでグラフ描画してもlogデータ数は、2時間程度動作させた位では減少することは
なくなりました。
ただ、やはり、メモリは徐々に増えて行ってます。
グラフなしでタイマー時間を200ms、400msにしても若干ゆっくりに見えますが、メモリ
は増加しています。
タイマーイベントの処理内容でメモリ増加をしているのがあるということですよね。
こういうのもあったけど
http://nanoappli.com/blog/archives/2577
http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1575
パフォーマンスモニターだけが正しいわけでもないみたいですね。
>タイマーイベントの処理内容でメモリ増加をしているのがあるということですよね
そうですね、もう一度タイマーイベントの処理を調べてみたらどうでしょうか?
追記
PIC側のシフト開発者とは連絡取れないのでしょうか?
一度、通信フローも見直した方がいいかも知れないです。
本当にタイマーイベント内で処理できるのかも調べたほうがいいと思います。
あと、1s,2s.....ではどうなりますか?
それで落ち着くのなら、スレッド化を考えたほうがいいと思います。
修正です。
PIC側のソフト開発者とは連絡取れないのでしょうか?
です。
タイマーイベントの処理を一度コマンドデータのWriteFile(WriteHandle,
&OutputPacketBuffer,65, &BytesWritten, 0);と受信データの
ReadFile(ReadHandle,&InputPacketBuffer, 65, &BytesRead, 0);関数だけにして行ったところ
メモリの増加は止まった様に思えます。
そうすると、PICとの通信フローは問題ない様に思えるのですが・・・
因みにPICのソフト担当者は私です。システム全体を引き継いだので・・・
次は、タイマーイベントの処理内容をひとつひとつコメントアウトして、潰していこうかと思っ
ています。
受信データ後の処理は、受信データの配列保存、データ表示用の演算、データ表示、データの
csvファイル保存、グラフ描画になります。
もし、スレッド化する場合は、結構大変なのでしょうか。
>タイマーイベントの処理を一度コマンドデータのWriteFile(WriteHandle,
>&OutputPacketBuffer,65, &BytesWritten, 0);と受信データの
>ReadFile(ReadHandle,&InputPacketBuffer, 65, &BytesRead, 0);
>関数だけにして行ったところ
>メモリの増加は止まった様に思えます。
>そうすると、PICとの通信フローは問題ない様に思えるのですが・・・
ならよかったです。
問題あると、通信フローの見直し等大変です。
>もし、スレッド化する場合は、結構大変なのでしょうか。
仕上がっているソフトを変えるのは大変だと思います。
ただ、フロー等、資料があるみたいですので、ひとつひとつ確認しながら
組み立てていけば意外とスム-ズにいくかもしれませんね。
スレッド化検討は、
受信データの配列保存、データ表示用の演算、データのcsvファイル保存
の中で処理が詰まっているのをするのがいいと思います。
データ表示、グラフは見るうえでの不具合がない限り、遅いタイミング
でいいと思います。
少し、間が空いて仕舞いましたが、何と無く分かってきました。
メモリが段々増えて行くのは、グラフ描画と常にUSBの接続確認をするための関数と分かりまし
た。グラフに関しては、ある一定範囲の描画とするとグラフ描画によるメモリ増加は、無くなりま
した。あとは、USBの接続確認ですが、ここでの接続確認は、最初にUSB機器に接続する為に使用
している関数と同じ関数を名前替えて作り、その関数を常に通るようにして、USB機器が接続して
いるかを確認してました。
これについて何処でメモリリークしているかを確認中です。
USBに関する部分は、かなり高度なので、ご教示頂ければと思います。
ソースは、ここに記載しても良いのでしょうか。
たぶんいいと思いますが、あまり長いようだと嫌がる方がいますね。
ソースは、以下のサイトのPIC18 汎用クラス Microchip社デモソフト(WinUSBドライバ編)の
System::Void Connect_btn_Click(System::Object^ sender, System::EventArgs^ e) 関数部
分と同じになります。
http://www.ys-labo.com/VC%20Tips/2009/VC%20Tips%20USB.html
以下のソースになり、mallocをFreeにしてもまだリークしています。
このconnect_check関数を使用せずに、定期的にUSBデバイスが接続されているかを確認す
る方法はありませんでしょうか。
void Connect_check( void )
{
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00,
0x11, 0x11, 0x00, 0x00, 0x30};
HDEVINFO DeviceInfoTable = INVALID_HANDLE_VALUE;
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFA
CE_DATA;
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP
_DEVICE_INTERFACE_DETAIL_DATA;
SP_DEVINFO_DATA DevInfoData;
DWORD InterfaceIndex = 0;
DWORD StatusLastError = 0;
DWORD dwRegType;
DWORD dwRegSize;
DWORD StructureSize = 0;
PBYTE PropertyValueBuffer;
bool MatchFound = false;
DWORD ErrorStatus;
String^ DeviceIDToFind;
DeviceIDToFind = MY_DEVICE_ID_24F;
DeviceInfoTable = SetupDiGetClassDevsUM(&InterfaceClassGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
while(true)
{
InterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA
);
if(SetupDiEnumDeviceInterfacesUM(DeviceInfoTable, NULL, &Interfa
ceClassGuid, InterfaceIndex, InterfaceDataStructure))
{
ErrorStatus = GetLastError();
if(ERROR_NO_MORE_ITEMS == ErrorStatus)
{
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
return;
}
}else{
timer1->Enabled = false ;
Connect_Error = true;
ErrorStatus = GetLastError();
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
//メッセージ表示
MessageBox::Show( 接続が切れました。,WARNING,Messag
eBoxButtons::OK,MessageBoxIcon::Warning);
return;
}
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiEnumDeviceInfoUM(DeviceInfoTable, InterfaceIndex, &DevInf
oData);
SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData
, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwRegSize);
PropertyValueBuffer = (BYTE *) malloc (dwRegSize);
if(PropertyValueBuffer == NULL)
{
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
return;
}
SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData
, SPDRP_HARDWAREID, &dwRegType, PropertyValueBuffer, dwRegSize, NULL);
#ifdef UNICODE
String^ DeviceIDFromRegistry = gcnew String((wchar_t *)PropertyV
alueBuffer);
#else
String^ DeviceIDFromRegistry = gcnew String((char *)PropertyValu
eBuffer);
#endif
free(PropertyValueBuffer);
DeviceIDFromRegistry = DeviceIDFromRegistry->ToLowerInvariant();
DeviceIDToFind = DeviceIDToFind->ToLowerInvariant();
MatchFound = DeviceIDFromRegistry->Contains(DeviceIDToFind);
if(MatchFound == true)
{
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVIC
E_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, Inter
faceDataStructure, NULL, NULL, &StructureSize, NULL);
DetailedInterfaceDataStructure = (PSP_DEVICE_INTERFACE_D
ETAIL_DATA)(malloc(StructureSize));
if(DetailedInterfaceDataStructure == NULL)
{
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
return;
}
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVIC
E_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, Inter
faceDataStructure, DetailedInterfaceDataStructure, StructureSize, NULL, NULL);
WriteHandle7 = CreateFile((DetailedInterfaceDataStructur
e->DevicePath), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EX
ISTING, 0, 0);
ErrorStatus = GetLastError();
//if(ErrorStatus == ERROR_SUCCESS)
//ToggleLED_btn->Enabled = true;
ReadHandle7 = CreateFile((DetailedInterfaceDataStructure
->DevicePath), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXIS
TING, 0, 0);
ErrorStatus = GetLastError();
if(ErrorStatus == ERROR_SUCCESS)
{}
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
return;
}
InterfaceIndex++;
}
}
Connect_checkの関数中のCreateFileは、でオ-プンしたハンドルはクローズしています
か?
Connect_checkは一回だけ実行すればいいですね。