|
메모리 누수가 의심되신다면..
memproof라는 툴을 써보세요..
이 툴에서 실행파일을 불러 실행시키면..
사용하는 메모리가 모니터링 되고..
종료후에는 해지가 되지 않은 메모리가 표시됩니다.
누수가 되는 곳을 클릭하면.. 소스까지 보여주므로 정말 편리합니다.
더구나 공개입니다.
델파이용으로 나온건데.. 빌더용도 있습니다.
mach9 님이 쓰신 글 :
: <<서문>>
: 저는 PLC에서 RS-232로 데이타를 읽어와서
: 1초에 한번꼴로 파라독스DB에 레코드를 생성하는
: 프로그램을 만들고 있습니다. 소위 이야기하는 MMI(Man-Machine-Interface)프로그램의
: 데이타 로깅(Logging)부분입니다.
: 통신모듈에 CPU TIme을 빼앗기면 안되기 때문에
: 통신관련Thread(이하 "■") 와 데이타로깅Thread(이하 "▲") 둘을 이용하고 있습니다.
: 앞에서 언급한 ■에 CPU TIme을 빼앗기면 안되기 때문에 Priority를 3~4로주고
: ▲에 0을 주었습니다.
:
: <<본론>>
: 문제는 ▲에서 발생합니다.
: - ■에서 TQueue로 TSmallIntArray로 정의된 배열 데이타가 계속 할당생성(New)되어서 Push됩니다.
: - ▲에서 TQueue로부터 TSmallIntArray는 Pop되어 ParaDox DB 에Append 된뒤 delete됩니다.
: 문제점 ===> ▲에서 일정시간이 지나면(1시간 또는 2시간 특히 정한 시간이 없음)
: PC가 SHotDown 됩니다.
: - DB에 이상이 있을 수도 있을까봐 Personel Oracle를 쓰봐도 마찬가집니다.
: - 제생각에 TSmallIntArray를 계속 New 하고 Delete하는 과정에서 Error가 나는 것이 아닐런지 ?????
: 원형Queue를 사용하면 메모리 할당을 계속 하지 않으면 괜챤을지..(아직 해보지 않아서)
: 어떻게 해야할지 모르겠습니다.
: - DB상에 문제라면 TExt 파일로 저장해서 하루에 한번씩 batch로 DB에 넣어야 할까요...
: 이러면 문제가 많습니다.
: - 해결해주시면 제가 한잔 사겠습니다. 창원에 내려 오시면...내려 오기전에 메일 주세요 꼭...
:
: ■------------------------------
: ....
: 통신 모듈
: ......
:
: QueueAnalog->Push(AnalogSmallIntArray);
: AnalogSmallIntArray = new TSmallIntArray(0,0);
: if(QueueAnalog->Count() > 10){
: if(!m_ExistThreadAnalogLogging){
: ThreadAnalogLogging = new TThreadAnalogLogging(true); //Thread 만들어지지 않았다면 생성
: m_ExistThreadAnalogLogging = true;
: ThreadAnalogLogging->FreeOnTerminate =true; // Set FreeOnTerminate to true if you want to explicitly destroy threads after they finish executing.
: ThreadAnalogLogging->Priority = StrToInt(ComboBoxThreadAnalog->Text);
: }
: if(ThreadAnalogLogging->Suspended){
: ThreadAnalogLogging->Resume();
: LabelMessage2->Caption = "ThreadAnalogLog Resume !" ;
: }
: }
:
:
: ▲----------------------------------
: void __fastcall TThreadAnalogLogging::Execute()
: {
: int i=0;
: AnsiString strTemp0="";
: TSmallIntArray *AnalogSmallIntArray;
: //---Thread 무한 루프----------------------------------------------------------------------------
: TableAnalogLog->Open();
: while(!Terminated)
: {
: if(QueueAnalog->Count() == 0){
: LabelMessage2->Caption = "ThreadAnalogLog is Terminated!" ;
: ThreadAnalogLogging->Terminate();//Thread0->Terminated = true로 됨
: m_ExistThreadAnalogLogging = false;
: continue;
: }
:
: if(QueueAnalog->Count() > 0)
: {
: AnalogSmallIntArray = (TSmallIntArray*)QueueAnalog->Pop();
: //--- Disk Logging ------------------------------------------------------------------------
: //향후에 PLC System 시간을 전송받아서 사용해야함.
: TableAnalogLog->Append();
: TableAnalogLog->FieldValues["AnalogDate"] = FormatDateTime("yyyy-mm-dd", Now());
: strTemp0.printf("%02d:%02d:%02d:%03d",(int)AnalogSmallIntArray->GetItem(0),
: (int)AnalogSmallIntArray->GetItem(1),
: (int)AnalogSmallIntArray->GetItem(2),
: (int)AnalogSmallIntArray->GetItem(3));
: TableAnalogLog->FieldValues["AnalogTime"] = strTemp0;
: TableAnalogLog->FieldValues["Analog0"] = (int)AnalogSmallIntArray->GetItem(0);
: TableAnalogLog->FieldValues["Analog1"] = (int)AnalogSmallIntArray->GetItem(1);
: TableAnalogLog->FieldValues["Analog2"] = (int)AnalogSmallIntArray->GetItem(2);
: TableAnalogLog->FieldValues["Analog3"] = (int)AnalogSmallIntArray->GetItem(3);
: TableAnalogLog->FieldValues["Analog4"] = (int)AnalogSmallIntArray->GetItem(4);
: TableAnalogLog->FieldValues["Analog5"] = (int)AnalogSmallIntArray->GetItem(5);
: TableAnalogLog->FieldValues["Analog6"] = (int)AnalogSmallIntArray->GetItem(6);
: TableAnalogLog->FieldValues["Analog7"] = (int)AnalogSmallIntArray->GetItem(7);
: TableAnalogLog->FieldValues["Analog8"] = (int)AnalogSmallIntArray->GetItem(8);
: TableAnalogLog->FieldValues["Analog9"] = (int)AnalogSmallIntArray->GetItem(9);
: try{ TableAnalogLog->Post(); }
: catch(Exception &E)
: {
: LabelErrorMessage->Caption = "TableAnalogLog-->" + E.Message;
: TableAnalogLog->Cancel();
: }
: delete AnalogSmallIntArray;
: } //if(QueueAnalog->Count() > 0)
: } //while((!Terminated)
: TableAnalogLog->Close();
: }
:
:
|