INSPECT기타 메모리 누수(Memory Leak) 정리INSPECT 2017. 2. 7. 20:44 어떻게 죽는가? 분석C 소스 코드를 보면서 얘기하겠습니다.
함수 내에서 선언해서 사용하는 변수는 지역변수로 컴퓨터 구조의 스택이라는 자료구조 내에 보관됩니다. 위 코드 내의 정수형 foo가 이 경우에 해당되는데 이 변수를 지역변수라고 합니다. 지역 변수는 함수가 종료될 때, 자동으로 사라집니다. 문제가 되는 것은 buf 변수입니다. 이 변수는 malloc 함수를 통해서 힙(Heap) 영역의 메모리를 할당받아서 사용하는데, 이 힙 영역의 메모리를 할당 받으면 명시적으로 메모리 해제를 해줘야 합니다. 하지만 fread 함수를 통해서 파일 읽기가 실패하면 11번 째 줄에서 NULL을 리턴하고 함수가 종료되는데요, 바로 여기서 메모리 누수가 발생합니다. 힙 영역의 메모리를 할당 받은 buf 변수가 free를 통해서 해제되지 않았기 때문입니다. 이 경우 프로그램이 종료되어도 해당 메모리 공간을 다시 사용할 수가 없으며, 이런 메모리 누수가 누적되면 결국 시스템 전체의 메모리 부족 현상이 발생할 수 있습니다. 아래와 같은 경우도 생깁니다.
이 경우는 bar 포인터 변수가 힙 영역에 할당된 메모리 200바이트를 가리키고 있는데, bar의 주소 값에 foo의 주소 값을 대입하게 되면 이전에 bar 변수를 통해 할당한 힙 영역의 메모리 200바이트에 접근할 방법이 사라집니다. 이 경우에도 메모리 누수가 생깁니다.
이 경우에는 구조체 my_struct의 필드인 foo가 힙 메모리 영역을 100바이트 할당 받았으나, 그 부모인 entity 가 먼저 해제되어서 foo에 접근해서 해제할 방법이 없어진 경우입니다. 이 코드를 실행하면 100바이트의 메모리 누수가 발생합니다.
위 코드의 경우 get_buffer() 함수가 힙 메모리에서 100바이트를 할당해서 그 포인터를 반환하지만 test_func() 함수에서는 이를 받는 변수가 없습니다. 이 경우에도 힙 메모리에 할당된 100바이트에 접근할 방법이 사라지기 때문에 메모리 누수가 발생합니다. 찾기 힘들다위의 코드는 메모리 누수가 어떻게 일어나는지를 한 눈에 볼 수 있도록 단순화 시켜서 메모리 누수 원인을 빠른 시간 안에 정확하게 찾을 수 있습니다. 하지만 일반적으로 방대한 소스코드로 개발된 복잡한 프로그램에서 메모리 누수를 찾기란 매우 어렵습니다. 시스템 자원을 감시하거나 메모리 할당 실패 시 별도의 로그를 기록하지 않으면 특히 더 찾기 어렵습니다. 오류를 재현하기도 힘들 뿐더러 불규칙적인 시간과 증상을 보이면서 시스템이 장애를 일으키기 때문에 원인이 정확하게 무엇인지 추정할 수 없게 만듭니다.?메모리 누수는 프로그램뿐만 아니라 전체 시스템에 영향을 주기 때문에 해당 컴퓨터에서 작동 중인 모든 소프트웨어를 다 검사해야 하기도 합니다. 자바, 안드로이드, Objective-C 에도 존재예제로 C 언어로 된 코드를 사용했지만 메모리 누수는 비단 C와 C++에만 존재하는 것이 아닙니다. 동적으로 할당한 메모리 중 필요 없게 된 영역을 해제하는 가비지 콜렉터(Garbage Collector) 기법을 이용하는 자바와 안드로이드에도 엄연히 메모리 누수가 존재합니다. 다만 앞서 소개한 C/C++ 코드에서 같이 할당한 힙 영역을 접근할 수 있는 포인터가 사라지는 경우에는 자바의 가비지 콜렉터가 동작해서 할당한 힙 영역을 다시 사용할 수 있게 해줍니다. 자바의 메모리 누수가 문제가 되는 경우는 Loitering Object 입니다. Loitering 의 뜻은??’어슬렁거리다, 서성이다’ 라는 뜻인데요, 아래의 코드에서 나타날 수 있습니다.
이 코드는 ArrayList형 변수 array에 SomeObject라는 객체를 추가했으나, 작업 후 array 내부의 객체를 제거하지 않음으로서 메모리 누수가 발생하는 코드입니다. ?이 경우 obj는?Loitering Object가 되서 obj가 할당한 메모리가 시스템으로 반환되지 않고 계속 메모리를 점유하게 됩니다. 보안도 위협이 메모리 누수는 대부분의 경우 시스템을 전반적으로 불안정하게 만들지만, 때에 따라서는 보안에도 큰 위협이 될 수 있습니다. 메모리 누수가 있는 프로그램을 공격하여 시스템을 중단시키거나, 임의의 코드를 실행할 수 있으며, 메모리 부족 조건 하에서 발생하는 예기치 못한 동작을 이용해서 시스템을 공격할 수도 있습니다. 메모리 누수 탐지 방법 Java와 같은 언어에서는 메모리 누수를 탐지하는 도구가 있고 C/C++의 경우 프레임워크에서 지원하는 라이브러리가 있습니다. 윈도우즈의 CRT 라이브러리가 그 예가 되겠죠. 유명한 정적 코드 분석도구에서도 메모리 누수를 탐지하는 기능을 제공합니다. 원문 : http://story.wisedog.net/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98-memory-leak%EB%9E%80/ |