데몬의 메모리 누수문제
안녕하세요. 씨를 공부하고 있는 초보 개발자입니다.
이번에 데몬을 만들어서 서비스를 하고 있는데요
원인을 알수 없는 메모리누수 문제때문에 삽질을 열심히..하고 있습니다.
.. 네트워크 서버프로그램입니다.
Makefile에 옵션설정으로 데몬방식으로 컴파일할수도 있고
그냥 일반 애플리케이션으로 컴파일할 수도 있는데요
일반애플리케이션으로 동작할때는 메모리 누수 현상이 발생하지
않는데.. 데몬방식으로 동작할때는 메모리누수현상이 발생합니다.
top 명령으로 확인해보면 점차적으로 메모리가 올라갑니다.
아주 조금씩 올라가기때문에 패킷을 많이 날려본 후에야 알았습니다.
제 생각에 데몬방식은 파일에 로그를 남기고, 일반애플리케이션은
stdout에 로그를 남기는 차이일뿐인데...
데몬만들때 fork()를 두번에서 부모프로세스가 init 이 되도록 했습니다.(fork()를 한번 해도 되긴 하겠지만..걍 확실히 하기 위해서 ..)
혹시 비슷한 경험이 있으시거나
데몬방식과 일반 애플리케이션 방식에서 실수할 수 있는 부분을
말씀좀 해주십시요
해결할 수 있는 툴에 대한 소개도 감사..답답해서 미치겠네요
아무말이나 좀 던져주십시요
------------- 참고 --------------
개발환경은
SunOS 5.7 Generic_106541-36 sun4u sparc SUNW,Ultra-60 이구요
멀티스레드 형식으로 동작하거든요
클라이언트 요청이 오면 큐에 집어넣었다가 스레드풀( 비스무리하게 구현)에서 하나 꺼내와서 작업을 하는 방식입니다.
accept() 하는 스레드는 enque하고 pthread_cond_signal()해주고, 스레드 풀의 어떤 스레드는 deque하는 방식입니다.
(학교에서 생산자-소비자 알고리즘이라고 과제작성한적 있는데 그와 비슷한 방식이겠죠.. )
큐에 들어가는 내용은 클라이언트의 소켓번호(4바이트)뿐입니다.
malloc하는 곳과 free하는 곳을 다 꼼꼼히 체크해 보세요.
malloc하는 곳과 free하는 곳을 다 꼼꼼히 체크해 보세요.
일반 어플리케이션으로 컴파일 했다는 말씀은 1회만 실행된다는 의미인
일반 어플리케이션으로 컴파일 했다는 말씀은
1회만 실행된다는 의미인 것 같습니다.
1회만 실행이 된다면 아마 메모리 누수 현상을 찾기가 힘들겠지요.
데몬으로 실행한다면 계속 메모리 할당과 해제를 해야하는데,
아마도 메모리 할당만 하고 해제를 제대로 못하는 것으로 추측되어 집니다.
아 답변 감사감사..
관심과 답변 갑사합니다.
일반애플리케이션도 루프를 돌면서 프로그램이 실행됩니다.
데몬이랑 동일하게 동작하구요
메모리 문제는 큐를 미리 할당하기 때문에...더이상 체크할 곳이 없습니다.
큐에서 읽어올때 아래와 같이 읽어오는 방식이거든요
아무튼 관심과 답변 갑사합니다.
@.@
[quote]Makefile에 옵션설정으로 데몬방식으로 컴파일할수도 있고
그렇다면 데몬으로 컴파일 할때와 일반 애플로 컴파일 할때의
차이를 보시는 게 좋을 것 같습니다.
...
데몬으로 컴파일할때는 위의 코드가 컴파일이 됩니다.
그리구 차이점이라면 데몬일때 로그내용이 파일에 저장되는 것인데요
(일반 애플리케이션일때는 그냥 stdout으로)
그렇다면 로그내용이 파일에 저장될때 메모리 누수가 발생하는가 싶은 생각이 들어서
로그를 아예 남기지 않도록 테스트를 해보았습니다.
그래도 마찬가지였습니다.
제가 아는 차이점에 대해서는 다 테스트해보았는데 더 이상은 모르겠네요
위의 경우에 발생가능한... 실수 또는 오류가 어떤것이 있는지 궁금합니다.
답변 감사드립니다.
사족) 이런거 보면 자바가 얼마나 편한건지..새삼 느낍니다.
메모리가 부족하면 램하나 추가하면 되거든요
안전한 프로그램이 램값보다 중요하니까.. 이휴
@.@
top 명령으로 해보면..
top 명령으로 해보면..
SIZE RES 필드가 늘어나는데 왜 그런지 알수가 없네요
@.@
Re: 아 답변 감사감사..
일단, '있다'에 삼선짬뽕 하나 걸겠습니다!
아마 이 경우는 아니라고 생각되지만서도, 혹시 외부 라이브러리 사용하시는 것이 있다면 해당 라이브러리에
메모리 누수 문제 버그보고가 올라와 있는지 확인해 보세요.
IPC나 regex 도 내부적으로 malloc을 사용하니, leak의 원
IPC나 regex 도 내부적으로 malloc을 사용하니, leak의 원인이 됩니다.
semdt() 이라든지, reg_free() 등을 잊으신 건 아닌지도 확인해 보세요.
----
Let's shut up and code.
Re: 아 답변 감사감사..
이 긴글을 읽어주실분이 계실런지..
일단............. ipc,regex는 사용하지 않습니다.
바로 윗글을 읽고...혹시 시간관련..라이브러리에서
내부적으로 메모리 누수의 문제가 있지는 않나 궁금해지는군요
원하신다면 전체소스도 공개해드립니다. ㅠㅠ
버그를 찾기만 하면 삼선짬뽕은 제가 사드릴께요.. 진짜 사드림 ㅎㅎ (단, 버그찾아주시면 ㅋㅋ)
일단 시스템 초기화시에 큐 메모리를 할당해 놓으므로 더이상의 malloc은 없습니다. (적어도 제가 직접 malloc 하지는 않습니다)
그리고 네트워크 관련 함수들은 스티븐스아저씨의 소스를 그대로 카피해왔으므로 버그의 가능성에서 제외시켜보겠습니다.(하지만 맨밑에 첨부는 했음)
그 다음... 시간관련 라이브러리에 문제가 있지 않을까 생각이 듭니다. 시간관련 라이브러리에 대해 제가 정확히 그 내부동작을 이해하는 것은 아니라서.. 조금 의심이 가는군요.
디버깅을 위해 아래와 같은 매크로를 선언했습니다.
위의 매크로에서는 아래의 format_time()을 사용합니다.
로그관련 함수들을 정의해놓은 파일 log.c는 아래와 같습니다.
로그파일 이름은 예를 들면 a.20050228.2644.0 인데
a.날짜.ProcessId.일련번호 입니다.
일련번호는 20메가 이상이면 일련번호가 증가합니다.
참고로
스티븐스아저씨의 소스코드를 긁어서 나름대로 만든 소스도
첨부시켜드립니다.
@.@
Re: ...
자바라고 무결할까요? 70년대 부터 GC를 쓴 환경에서도 버그는 발견됩니다. :twisted:
- 죠커's blog / HanIRC:#CN
댓글 달기