메모리 누수가 괜찮습니까? [닫은]

C 또는 C ++ 응용 프로그램에서 메모리 누수가 발생 하는 것이 허용 됩니까?

메모리의 일부를 할당하고 응용 프로그램의 마지막 코드 줄 (예 : 전역 객체의 소멸자)까지 사용하면 어떻게 되나요? 메모리 소비가 시간이 지남에 따라 증가하지 않는 한, 응용 프로그램이 종료 될 때 (Windows, Mac 및 Linux에서) 메모리를 확보하기 위해 OS를 신뢰해도 괜찮습니까? 메모리가 OS에 의해 해제 될 때까지 메모리를 계속 사용했다면 이것을 실제 메모리 누수로 간주하겠습니까?

만약 제 3 자 도서관이 당신에게 이런 상황을 강요한다면? 아무리 크든 상관없이 해당 타사 라이브러리를 사용하지 않겠습니까?

하나의 실질적인 단점 만 보았습니다. 즉, 이러한 양성 누출은 메모리 누출 탐지 도구와 함께 오탐 (false positive)으로 표시됩니다.



답변

아니.

전문가로서 우리 자신에게 묻지 말아야 할 질문은 “이 작업을해도 괜찮습니까?”입니다. 그러나 오히려 “이것이 좋은 이유가 있습니까?” “메모리 누수를 찾아내는 것은 고통스러운 일”이라고해서 좋은 이유는 아닙니다.

나는 일을 단순하게 유지하고 싶다. 그리고 간단한 규칙은 내 프로그램에 메모리 누수가 없어야한다는 것입니다.

그것은 내 인생도 단순하게 만듭니다. 메모리 누수를 감지하면 “허용 가능한”메모리 누수인지 확인하기 위해 정교한 의사 결정 트리 구조를 실행하는 대신이를 제거합니다.

컴파일러 경고와 비슷합니다. 경고가 특정 응용 프로그램에 치명적입니까? 아마.

그러나 그것은 궁극적으로 전문적인 훈련의 문제입니다. 컴파일러 경고를 허용하고 메모리 누수를 허용하는 것은 나쁜 습관입니다.

극단적 인 일을하기 위해 외과 의사가 환자에게 수술 장비를 남겨 두는 것이 허용 될 수 있습니까?

해당 장비를 제거하는 비용 / 위험이 장비를 떠나는 비용 / 위험을 초과하는 상황이 발생할 수 있지만 SurgeonOverflow.com에 게시 된이 질문을 보면 무해한 환경이있을 수 있습니다. “아니오”이외의 대답을 보았을 때, 그것은 의료계에 대한 나의 확신을 심각하게 약화시킬 것입니다.

제 3 자 도서관이 저 에게이 상황을 강요하면 문제의 도서관의 전반적인 품질을 심각하게 의심하게됩니다. 마치 테스트를 통해 차를 몰고 컵 홀더 중 하나에서 느슨한 와셔와 너트를 발견 한 것처럼 보일 것입니다. 그 자체로는 큰 문제는 아니지만 품질에 대한 헌신이 부족한 것으로 보아 대안을 고려할 것입니다.


답변

“사용중인”메모리 양이 계속 증가하지 않는 한 메모리 누수로 간주하지 않습니다. 필요한 메모리 양이 계속 증가하지 않는 한, 릴리스되지 않은 메모리가 이상적이지는 않지만 큰 문제는 아닙니다.


답변

먼저 우리의 정의를 올바르게 해봅시다. 메모리 누수 는 메모리가 예를 들어 with로 동적으로 할당 malloc()되고 해당 여유 공간없이 메모리에 대한 모든 참조가 손실되는 경우입니다. 하나를 만드는 쉬운 방법은 다음과 같습니다.

#define BLK ((size_t)1024)
while(1){
    void * vp = malloc(BLK);
}

while (1) 루프를 돌 때마다 1024 (+ overhead) 바이트가 할당되고 새 주소가 vp에 할당됩니다. 이전 malloc’ed 블록에 대한 나머지 포인터가 없습니다. 이 프로그램은 힙이 다 떨어질 때까지 실행되며 malloc의 메모리를 복구 할 방법이 없습니다. 메모리가 힙에서 “누설”되어 다시는 볼 수 없습니다.

하지만 당신이 묘사하는 것은

int main(){
    void * vp = malloc(LOTS);
    // Go do something useful
    return 0;
}

프로그램을 종료 할 때까지 메모리를 할당하고 작업하십시오. 이것은 메모리 누수 가 아닙니다 . 프로그램을 손상시키지 않으며 프로그램이 종료 될 때 모든 메모리가 자동으로 청소됩니다.

일반적으로 메모리 누수를 피해야합니다. 첫째, 당신보다 높은 곳에서 격납고에 연료를 공급하기 때문에 누출되어 복구 할 수없는 메모리는 쓸모가 없습니다. 둘째, 메모리 누수를 시작하지 않고 나중에 메모리 누수를 찾는 것보다 올바르게 코딩하는 것이 훨씬 쉽습니다.


답변

이론적으로 아니, 실제로 그것은 달려있다 .

그것은 실제로 프로그램이 작업하는 데이터의 양, 프로그램이 얼마나 자주 실행되는지 그리고 지속적으로 실행되는지에 달려 있습니다.

적은 양의 데이터를 읽는 빠른 프로그램이 계산을 끝내고 종료되면 작은 메모리 누수가 발견되지 않습니다. 프로그램이 오래 실행되지 않고 적은 양의 메모리 만 사용하기 때문에 프로그램이 존재할 때 누수가 작고 해제됩니다.

반면에 수백만 개의 레코드를 처리하고 오랫동안 실행되는 프로그램이 있으면 작은 메모리 누출로 인해 충분한 시간이 주어지면 시스템이 다운 될 수 있습니다.

누출이있는 타사 라이브러리의 경우 문제가 발생하면 라이브러리를 수정하거나 더 나은 대안을 찾으십시오. 문제가되지 않으면 실제로 문제가됩니까?


답변

많은 사람들이 일단 메모리를 확보하면 즉시 운영 체제로 돌아와 다른 프로그램에서 사용할 수 있다는 인상을 받고있는 것 같습니다.

사실이 아닙니다. 운영 체제는 일반적으로 4KiB 페이지에서 메모리를 관리합니다. malloc다른 종류의 메모리 관리는 OS에서 페이지를 가져오고 적절하다고 생각되면 하위 관리합니다. 그것은 아주 가능성이 있음을의 free()없는 프로그램이 나중에 더 많은 메모리를 malloc을 것이라는 가정하에, 운영 체제에 페이지를 반환합니다.

나는 free()결코 운영 체제에 메모리를 반환 하지 않는다고 말하지 않습니다 . 특히 많은 양의 메모리를 비우는 경우에 발생할 수 있습니다. 그러나 보장 할 수 없습니다.

중요한 사실 : 더 이상 필요하지 않은 메모리를 확보하지 않으면 추가 malloc이 더 많은 메모리 를 소비 하게 됩니다. 그러나 먼저 해제하면 malloc이 해제 된 메모리를 대신 재사용 할 수 있습니다.

이것이 실제로 무엇을 의미합니까? 즉, 프로그램에 더 이상 메모리가 필요하지 않다는 것을 알고 있다면 (예 : 정리 단계에 있음) 메모리를 해제하는 것은 그리 중요하지 않습니다. 그러나 프로그램이 나중에 더 많은 메모리를 할당 할 수 있으면 메모리 누수, 특히 반복적으로 발생할 수있는 메모리 누수를 피해야합니다.

또한 종료 직전에 메모리를 해제하는 것이 나쁜 이유에 대한 자세한 내용 은 이 주석 을 참조하십시오.

주석가는 호출 free()이 다른 프로그램이 해제 된 메모리를 자동으로 사용하도록 허용하지 않는다는 것을 이해하지 못하는 것 같습니다 . 그러나 이것이이 답변의 요점입니다!

따라서 사람들을 설득하기 위해 free ()가 거의 수행하지 않는 예를 보여 드리겠습니다. 수학을 쉽게 따르기 위해 OS가 4000 바이트 페이지에서 메모리를 관리하는 것처럼 가장합니다.

10,000 개의 100 바이트 블록을 할당한다고 가정합니다 (간단하게하기 위해 이러한 할당을 관리하는 데 필요한 추가 메모리는 무시합니다). 1MB 또는 250 페이지를 소비합니다. 그런 다음이 블록 중 9000 개를 임의로 해제하면 1000 개의 블록 만 남게됩니다. 통계적으로 약 5 페이지의 페이지가 비어 있습니다. 다른 245는 각각 적어도 하나의 할당 된 블록을 가질 것이다. 100KB 만 할당하더라도 운영 체제에서 회수 할 수없는 메모리는 980KB입니다.

한편, 프로그램이 묶는 메모리의 양을 늘리지 않고도 malloc () 9000 블록을 더 만들 수 있습니다.

기술적 으로 메모리를 OS에 반환 할 free()수있는 경우에도 그렇지 않을 수 있습니다. 빠른 운영과 메모리 절약 사이의 균형을 유지해야합니다. 또한 이미 많은 메모리를 할당 한 다음 해제 한 프로그램은 다시 그렇게 할 가능성이 있습니다. 웹 서버는 요청 후 요청 후 요청을 처리해야합니다. 일부 “느슨한”메모리를 사용 가능한 상태로 유지하면 OS에 항상 메모리를 요청할 필요가 없습니다.free()


답변

응용 프로그램을 실행 한 후 OS를 정리하는 데 개념적으로 잘못된 것은 없습니다.

실제로 응용 프로그램과 실행 방법에 따라 다릅니다. 몇 주 동안 실행해야하는 응용 프로그램에서 지속적으로 발생하는 누수를 처리해야하지만 너무 많은 메모리 필요없이 결과를 계산하는 작은 도구는 문제가되지 않습니다.

많은 스크립팅 언어가 주기적 참조를 가비지 수집하지 않는 이유가 있습니다. 사용 패턴의 경우 실제 문제가 아니므로 낭비되는 메모리만큼 많은 자원을 낭비하게됩니다.


답변

나는 대답이 아니오라고 생각하고, 메모리 누수를 허용하지 않으며, 명시 적으로 언급하지 않은 몇 가지 이유가 있습니다. 여기에는 훌륭한 기술 답변이 있지만 실제 답변은 더 사회적 / 인간적인 이유에 달려 있다고 생각합니다.

(먼저 언급했듯이, 진정한 누출은 프로그램이 어느 시점에서 할당 한 메모리 리소스를 잃어 버릴 때입니다. C에서 이것은 malloc()포인터를 가리키고 포인터가 범위를 벗어나지 않도록합니다. free()먼저.)

여기서 결정의 중요한 요지는 습관입니다. 포인터를 사용하는 언어로 코드를 작성하면 포인터 를 많이 사용하게 됩니다. 그리고 포인터는 위험합니다. 코드에 심각한 방식의 모든 문제를 추가하는 가장 쉬운 방법입니다.

코딩 할 때 때로는 공을 들고 때로는 피곤하거나 화를 내거나 걱정할 수도 있습니다. 다소 혼란스러운 시간에는 자동 조종 장치에서 더 많은 코딩 작업을 수행합니다. 자동 조종 장치 효과는 대규모 프로젝트에서 일회용 코드와 모듈을 구분하지 않습니다. 그 시간 동안, 당신이 설정하는 습관은 코드베이스에서 끝나는 것입니다.

따라서 현재 도로상에서 유일한 차 일지라도 차선을 변경할 때 사각 지대를 확인해야하는 것과 같은 이유로 메모리 누수를 허용하지 마십시오. 당신의 활동적인 두뇌가 산만해질 때, 좋은 습관이 당신을 재앙적인 실수로부터 구할 수있는 전부입니다.

“습관”문제 외에도 포인터는 복잡하며 정신적으로 추적하기 위해 많은 두뇌 능력이 필요합니다. 포인터를 사용할 때, 특히 프로그래밍을 처음 접할 때 “물을 진흙탕으로 치지”않는 것이 가장 좋습니다.

더 사회적 측면도 있습니다. 의 적절한 사용으로 malloc()하고 free(), 당신의 코드를 보이는 사람이 편안하게 될 것입니다; 당신은 당신의 자원을 관리하고 있습니다. 그러나 그렇지 않으면 즉시 문제가 의심됩니다.

어쩌면 메모리 누수로 인해이 컨텍스트에서 아무런 문제가되지는 않았지만 코드의 모든 관리자는 코드를 읽을 때도 머리에서 문제를 해결해야합니다. 를 사용 free()하면 문제를 고려해야 할 필요성도 제거됩니다.

마지막으로, 프로그래밍은 프로세스의 정신 모델을 모호하지 않은 언어로 작성하여 사람과 컴퓨터가 해당 프로세스를 완벽하게 이해할 수 있도록합니다. 좋은 프로그래밍 실습의 중요한 부분은 불필요한 모호함을 유발하지 않습니다.

스마트 프로그래밍은 유연하고 일반적입니다. 나쁜 프로그래밍은 모호합니다.