본문 바로가기
프로그래밍/delphi

델파이에서 호출하는 외부프로그램 메모리문제 해결하기

by 메르세데쓰 2015. 10. 21.
반응형

 

 

 

 

안녕하세요 메르세데스입니다.

 

이번에 AddOn 프로그램을 붙이는 것 때문에 고민을 하고 있습니다.

 

저희 사이트에서 사용하는 델파이 program에서 c#으로 만들어진 프로그램을 호출하는 것 때문에 문제가 생겼습니다.

 

뭐.. Call이야  제공해주는 메뉴얼에 나와있는 함수대로 진행하면 되니 큰 문제가 되지 않는데.. 문제는 메모리 누수입니다.

 

 

특이한 것은 마치 dll로 개발된 것 처럼..  별도의 실행파일이 돌아가서 process갯수가 늘어나는게 아니라..   메인Program의 메모리가 증가합니다.  하지만  호출된 것을 종료하면.. 반환이 제대로 안되는 문제가 발생합니다. 누적될수록.. 심각하네요!

 

 

한 두번이야 괜찮은데..   한번 띄우고 닫을 때 마다.. Memory가 조금씩 증가하더니..   20MB짜리가..  버튼을 눌러 10번정도 띄우고 닫고 하였더니 160M가 훌쩍 넘어갑니다. 

 

페이징으로 넘어가는 순간.. 잘 아시죠.. 미친듯이 느려지는 Program을 경험하게 될 것입니다.

 

 

호출 전 약 21MB 사용함
task manager (작업관리자)

 

뭐...단순한..일회성 프로그램이라면 그냥 마무리할 수 있지만.. 며칠씩 띄워놓고 사용해야 하는 것이기 때문에 이렇게 누수가 발생한다면..   곤란합니다.

 

10회 호출 후 약 160MB 사용함
task manager (작업관리자)

 

 

제가 소스를 갖고 있는게 아니라.. 분석도 할 수 없고..  답답할 노릇입니다.  대체 어떻게 만들어졌는지!!!!

 

 

델파이에서.. CreateComObject로 생성 한 것을 ..  object := nil 과 같은 것으로 처리를 해도 전혀 효과가 없습니다.  := nil은 그쪽에서 제공한 종료처리 함수에 들어있는 구문입니다.

 

근데 다음클리너나 네이버클리너.. 그리고 각종 클리어 프로그램을 보면..  기능 중  메모리 최적화를 하는 버튼이 있습니다. 가비지를 없애주는 것 인데요.. Memory누수 파악 및 해결이 쉽지 않은 상황이라면 혹시 이런 기능을 이용한다면 좀 도움이 되지 않을까 하는게 저의 생각입니다.

 

서론이 많이 길었습니다.

 

구글링을 좀 하다보면 힌트를 얻을 수 있습니다.  

 

Trim Process Memory delphi 라는 검색어로 찾아보시면 원하시는 결과를 얻으실 수 있을 것입니다.  

 

제 포스팅의 초점은... 줄줄세는 메모리의 소스를 분석해서 문제를 해결하는게 아닌, 다음클리너 처럼 최적화 함수를 사용하여 가비지 제거로 문제를 해결 하는 방법입니다.  100점짜리 답안은 아니죠.. 

 

타이머를 걸어 주기적으로 돌아가게 하던가.. 문제가 되는 호출 버튼에 걸어 두는 겁니다. 제 프로그램이 아니잖아요..^^  제 선에서 해결할 수 있는 가장 합리적인 방법이라 생각합니다.

 

Windows.pas에서 제공하는 함수를 이용한다면 .. Memory clean up을 할 수 있습니다.  알면 알수록.. 어렵습니다. 역시 기초가 중요합니다.

 

 

SetProcessWorkingSetSize
SetProcessWorkingSetSize

 

*참조

http://stackoverflow.com/questions/2031577/can-memory-be-cleaned-up

 

적용 후 아래처럼..  확 줄어든 것이 보이죠! 하지만 이렇게 클리어가 된 후 동일한 기능/버튼을 눌러 재실행 하면.. 

 

이전보다 구동시간이 약간 늘어난 것이 느껴질 수 있습니다. 체감하기 어려울 정도이긴 합니다만...

 

이유는  필요한 리소스를 메모리에 올려야하기 때문에 그런 것이겠죠?  하지만.. 컴퓨터가 멈추거나 다운되는 것 보다야 쪼금 느린게 훨씬 낫지 않을까요?

 

 

 

메모리 clean up함수 적용 후 원래대로 돌아옴
task manager (작업관리자)

 

 

SetProcessWorkingSetSize 함수를 이용하여..   해당 handle의 프로그램의 가비지를 제거 하는 것이지요.. 조금 응용을 한다면 내가 지정 한 Program을 대상으로 할 수 있을 것 같습니다. 하지만 저도 충분한 테스트를 해보질 못해서 검증에는 조금 시간이 필요 할 것 같네요.  사용자가 베타테스터가 되겠네요.. 쉿~!!

 

 

도움이 되셨기를... 감사합니다.

 

 

 

반응형

댓글