많은 책과 튜토리얼에서 메모리 관리 관행이 스트레스를 받고 그것을 사용한 후에 메모리를 확보하지 않으면 신비 롭고 끔찍한 일이 일어날 것이라고 느꼈습니다.
나는 다른 시스템에 대해 말할 수는 없지만 (나에게 비슷한 관행을 채택한다고 가정하는 것이 합리적이지만) 적어도 Windows에서는 커널이 기본적으로 사용하는 대부분의 리소스 (홀수 소수 제외)를 정리하도록 보장됩니다 프로그램 종료 후 프로그램. 여기에는 다양한 것들 중에서 힙 메모리가 포함됩니다.
사용자가 파일을 사용할 수 있도록 파일을 사용한 후에 파일을 닫으려는 이유 또는 대역폭을 절약하기 위해 서버에 연결된 소켓의 연결을 끊고 싶은 이유를 이해하지만 어리석은 것처럼 보입니다. 프로그램에서 사용하는 모든 메모리를 미세 관리해야합니다.
지금, 나는이 질문은 당신이 필요로 얼마나 많은 메모리를 기반으로 당신이 당신의 기억을 처리하는 방법부터 다양한 것을 동의하고 당신이 그것을 필요로 할 때, 그래서이이 질문의 범위를 좁힐 것이다 : 나는의 조각을 사용해야하는 경우 내 프로그램 수명 동안 메모리가 부족한 경우 프로그램 종료 직전에 메모리를 해제해야합니까?
편집 : 복제본으로 제안 된 질문은 Unix 제품군 운영 체제에만 해당됩니다. 최고 답변은 Linux에만 해당되는 툴 (예 : Valgrind)도 지정했습니다. 이 질문은 대부분의 “일반”비 임베디드 운영 체제를 다루고 프로그램 수명 기간 동안 필요한 메모리를 확보하는 것이 좋은 방법이 아닌 이유입니다.
답변
프로그램 수명 기간 동안 메모리를 사용해야하는 경우 프로그램 종료 직전에 메모리를 해제해야합니까?
필수는 아니지만 몇 가지 단점뿐만 아니라 이점도있을 수 있습니다.
프로그램이 실행 시간 동안 메모리를 한 번 할당하고 프로세스가 끝날 때까지 메모리를 해제하지 않으면 메모리를 수동으로 해제하지 않고 OS에 의존하지 않는 것이 현명한 방법 일 수 있습니다. 내가 아는 모든 최신 OS에서 이것은 안전합니다. 프로세스가 끝나면 할당 된 모든 메모리가 시스템에 안정적으로 반환됩니다.
경우에 따라 할당 된 메모리를 명시 적으로 정리하지 않으면 정리를 수행하는 것보다 훨씬 빠를 수도 있습니다.
그러나 실행이 끝날 때 모든 메모리를 명시 적으로 해제하면
- 디버깅 / 테스트 중 mem leak detection 도구는 “false positives”를 표시하지 않습니다
- 할당 및 할당 해제와 함께 메모리를 사용하는 코드를 별도의 구성 요소로 옮기고 나중에 구성 요소의 사용자가 메모리 사용 시간을 제어해야하는 다른 컨텍스트에서 사용하는 것이 훨씬 쉬울 수 있습니다.
프로그램의 수명은 바뀔 수 있습니다. 아마도 귀하의 프로그램은 오늘날 일반적인 수명이 10 분 미만인 작은 명령 줄 유틸리티 일 수 있으며 10 초마다 kb의 일부로 메모리를 할당하므로 프로그램이 종료되기 전에 할당 된 메모리를 전혀 확보 할 필요가 없습니다. 나중에 프로그램이 변경되고 수명이 몇 주인 서버 프로세스의 일부로 연장 된 사용을 얻습니다. 따라서 사용되지 않은 메모리를 해제하지 않는 것은 더 이상 옵션이 아닙니다. . 즉, 전체 프로그램을 검토 한 후 할당 해제 코드를 추가해야합니다. 운이 좋으면 쉬운 일이지만 그렇지 않은 경우 너무 어려워서 장소를 놓칠 가능성이 높습니다. 그리고 당신이 그 상황에있을 때, 당신은 당신이 “무료”를 추가했으면 좋겠다
더 일반적으로, 쓰기 할당하고 많은 프로그래머들 사이에서 “좋은 습관”항상 관련 할당 해제 코드 페어 카운트 : 항상 이렇게하면 메모리 상황에 해제 코드를 잊어 확률이 감소 한다 해제합니다.
답변
프로그램 실행이 끝날 때 메모리를 비우는 것은 CPU 시간 낭비입니다. 마치 궤도에서 핵을 파기 전에 집을 정리하는 것과 같습니다.
그러나 때로는 짧은 실행 프로그램이 훨씬 오래 실행되는 프로그램의 일부로 바뀔 수 있습니다. 그런 다음 물건을 풀어야합니다. 이것이 어느 정도 생각되지 않았다면 상당한 재 작업이 필요할 수 있습니다.
이에 대한 한 가지 현명한 해결책은 “talloc”입니다.이 기능을 사용하면 많은 메모리 할당을 수행 한 다음 한 번의 호출로 모든 메모리 할당을 버릴 수 있습니다.
답변
가비지 콜렉션이 있는 언어 (예 : Scheme, Ocaml, Haskell, Common Lisp 및 Java, Scala, Clojure)를 사용할 수 있습니다.
(대부분의 GC-ED의 언어에서이없는 방법 하는 명시 적 및 수동 ! 때때로, 일부 값이 될 수있는 메모리 확정 , 예를 들면 GC와 런타임 시스템 만이 아닌, 그 값에 도달 할 때 파일 핸들 값을 닫을 것이 확실하고 신뢰할 수 없으며 대신 최종 처리가 보장되지 않기 때문에 파일 핸들을 명시 적으로 닫아야 합니다.
C (또는 C ++)로 코딩 된 프로그램 의 경우 Boehm의 보수 가비지 수집기를 사용할 수도 있습니다 . 당신은 모든 당신 대체 할 malloc
함께 GC_malloc
약 귀찮게하지 free
어떤 포인터를 -ing. 물론 Boehm의 GC 사용의 장단점을 이해해야합니다. GC 핸드북을 읽으십시오 .
메모리 관리는 프로그램의 글로벌 속성입니다. 어떤 식 으로든 전체 프로그램 속성이기 때문에 (그리고 주어진 데이터의 생동감) 구성이 아니며 모듈이 아닙니다.
마지막으로, 다른 사람들이 지적했듯이 free
힙 할당 C 메모리 영역을 명시 적으로 지정하는 것이 좋습니다. 많은 메모리를 할당하지 않는 장난감 프로그램의 경우 메모리가 전혀 사용되지 않도록 결정할 수도 있습니다 free
( 프로세스 가 종료되면 가상 주소 공간을 포함한 자원 이 운영 체제에 의해 해제 됨).
프로그램 수명 기간 동안 메모리를 사용해야하는 경우 프로그램 종료 직전에 메모리를 해제해야합니까?
아니요, 그렇게 할 필요는 없습니다. 그리고 많은 실제 프로그램은 전체 수명에 필요한 일부 메모리를 해제하지 않습니다 (특히 GCC 컴파일러는 일부 메모리를 해제하지 않습니다). 그러나 그렇게 할 때 (예를 들어 C 동적으로 할당 된free
특정 데이터 조각을 귀찮게하지 않음 ) 동일한 프로젝트에서 미래 프로그래머의 작업 을 용이하게 하기 위해 그 사실을 더 잘 언급 할 것 입니다. 사용되지 않는 메모리의 양은 제한되어 있고 사용 된 총 힙 메모리에 비해 상대적으로 적은 양을 유지하는 것이 좋습니다.
시스템은 free
종종 (예를 들어 POSIX 시스템에서 munmap (2) 를 호출하여) OS에 메모리를 해제하지 않지만 대개 메모리 영역을 future에서 재사용 가능한 것으로 표시합니다 malloc
. 특히 가상 주소 공간 (예 : /proc/self/maps
Linux에서 볼 때 proc (5) …. 참조)은 이후에 줄어들지 않을 수 있습니다 free
(따라서 유틸리티 는 프로세스에 사용 된 메모리와 같은 양을 사용 ps
하거나 top
보고합니다).
답변
그것은하지 않습니다 필요 당신은 당신이 실패 제대로 경우 프로그램을 실행하지 않을 것 같이. 그러나 기회가 주어지면 선택할 수있는 이유가 있습니다.
내가 반복적으로 접하는 가장 강력한 사례 중 하나는 누군가가 실행 파일에서 실행되는 작은 시뮬레이션 코드를 작성한다는 것입니다. “이 코드를 시뮬레이션에 통합하고 싶다”고 말합니다. 그런 다음 몬테카를로 달리기 사이에 다시 초기화하는 방법을 물어보고 그들은 나를 빈틈없이 바라 봅니다. “재 초기화 란 무엇을 의미합니까? 새로운 설정으로 프로그램을 실행하기 만하면됩니까?”
때때로 클린업으로 인해 소프트웨어를 훨씬 쉽게 사용할 수 있습니다. 많은 예제의 경우 무언가를 정리할 필요가 없다고 가정하고 해당 추정에 대한 데이터 및 수명을 처리하는 방법에 대해 가정합니다. 이러한 추정이 유효하지 않은 새로운 환경으로 이동하면 전체 알고리즘이 더 이상 작동하지 않을 수 있습니다.
얼마나 이상한 일이 생길 수 있는지에 대한 예를 보려면 프로세스 종료시 관리되는 언어가 마무리 작업을 처리하는 방법 또는 C #이 응용 프로그램 도메인의 프로그래밍 중지를 처리하는 방법을 살펴보십시오. 이러한 극단적 인 경우에 균열을 겪는 가정이 있기 때문에 그들은 매듭으로 묶습니다.
답변
어쨌든 수동으로 메모리를 비우지 않는 언어를 무시하는 중 …
지금 “프로그램”으로 생각하는 것은 어느 시점에서 더 큰 프로그램의 일부인 함수 또는 메소드가 될 수 있습니다. 그런 다음 해당 함수가 여러 번 호출 될 수 있습니다. 그런 다음 “수동으로 해제”해야하는 메모리는 메모리 누수가됩니다. 물론 그것은 심판의 소명입니다.
답변
언젠가는 프로그램을 변경하고 다른 프로그램과 통합하거나 여러 인스턴스를 순서대로 또는 병렬로 실행하고 싶을 가능성이 매우 높습니다. 그런 다음 수동으로이 메모리를 비워야하지만 더 이상 상황을 기억하지 못하므로 프로그램을 다시 이해하는 데 시간이 더 걸립니다.
그들에 대한 당신의 이해가 여전히 신선하면서 일을하십시오.
미래에 큰 수익을 낼 수있는 작은 투자입니다.
답변
아니요, 필요하지는 않지만 좋은 생각입니다.
“사용이 끝난 후에 메모리를 확보하지 않으면 신비 롭고 끔찍한 일이 일어날 것” 이라고 생각 합니다.
기술적 인 측면에서, 이것의 유일한 결과는 하드 한계에 도달하거나 (예 : 가상 주소 공간이 모두 소모 됨) 성능이 수용 할 수 없게 될 때까지 프로그램이 더 많은 메모리를 계속 사용한다는 것입니다. 프로그램이 종료 되려고한다면 프로세스가 실제로 존재하지 않기 때문에이 중 어느 것도 중요하지 않습니다. “신비하고 끔찍한 것”은 순전히 개발자의 정신 상태에 관한 것입니다. 메모리 누수의 원인을 찾는 것은 절대적인 악몽이 될 수 있으며 (이것은 과소 평가입니다), 누수가없는 코드를 작성하려면 많은 기술과 훈련이 필요합니다. 이 기술과 훈련을 발전시키기 위해 권장되는 접근법 은 프로그램이 종료 되더라도 더 이상 필요하지 않은 메모리 를 항상 확보 하는 것입니다.
물론 이것은 다른 사람들이 말했듯이 코드를 더 쉽게 재사용하고 조정할 수 있다는 이점이 있습니다.
그러나 프로그램 종료 직전에 메모리를 비우지 않는 것이 더 좋은 경우가 적어도 하나 있습니다.
수백만 개의 작은 할당을했으며 대부분 디스크로 스왑 된 경우를 고려하십시오. 모든 것을 해제하기 시작하면 부기 정보에 액세스 할 수 있도록 데이터를 즉시 폐기하기 위해 대부분의 메모리를 RAM으로 다시 교체해야합니다. 이렇게하면 프로그램을 종료하는 데 몇 분이 걸릴 수 있습니다! 말할 것도없이 그 시간 동안 디스크와 물리적 메모리에 많은 압력을가했습니다. 물리적 메모리가 부족한 경우 (다른 프로그램이 많은 메모리를 씹기 때문에 프로그램이 닫혀있을 수 있음) 여러 개체를 해제해야 할 때 개별 페이지를 여러 번 교체해야 할 수 있습니다. 같은 페이지이지만 연속적으로 해제되지는 않습니다.
대신 프로그램이 중단되면 OS는 디스크로 스왑 된 모든 메모리를 단순히 버립니다. 디스크 액세스가 필요하지 않기 때문에 거의 즉각적입니다.
OO 언어에서는 객체의 소멸자를 호출하면 메모리가 강제로 스왑됩니다. 이 작업을 수행해야 할 경우 메모리를 비울 수도 있습니다.