2012-04-02 3 views
4

c/C++로 작성된 프로그램 (데몬)이 있습니다. 그것은 완벽하게 실행되지만 일정 기간 (5 일, 1 주, 2 주일 수 있음) 후에는 많은 메가 바이트의 메모리를 할당하게됩니다. 나는 코드의 어떤 부분이 할당 된 메모리를 해제하지 않는지 이해할 수 없다. 시동시 메모리 사용은 약 20-30 메가 바이트입니다. 그런 다음 일정 기간이 지나면 이벤트가 발생하면 약 1Mb 시간당 천천히 커지고 종료되지 않은 경우 사용할 수있는 메모리가 없기 때문에 중단 될 수 있습니다.할당 된 메모리 블록 찾기

Valgrind를 사용해 보았는데 이미 약 500Mb의 메모리가 할당되어있는 경우 일반적인 방법으로 데몬을 종료했습니다. 셧다운 프로세스는 실제로 길었지만, Valgrind가 끝나면 mysql_init/mysql_close 프로 시저 (약 504 바이트는 확실하게 손실 됨)를 제외하고는 메모리 누수가 발견되지 않았다. Google은이 Mysql 누출에 대해 걱정하지 않기로하고 Valgrind와 같은 메모리 진단 도구가 누수라고 생각하는 몇 가지 이유를 제시합니다.

코드 부분이 메모리를 할당하지만 프로그램 종료시에만 해제된다는 것을 알지 못합니다. 나를 찾을 수 있도록 도와주세요

+0

코드가 기존의 의미에서 메모리를 누설하지 않을 수 있지만 이러한 유형의 리소스 문제는 수시로 발생하며 코드를 안팎으로 알고 있어도 일반적으로 찾기가 어렵습니다. 코드를 보지 않고는 어떤 일이 발생했는지 알 수 없습니다. – Chad

+2

Valgrind의 도구 Massif는이 경우 기본 도구 Memcheck보다 더 유용 할 것입니다. – ninjalj

답변

4

Valgrind는 삭제되지 않은 포인터 만 감지합니다. 당신이 그들을 필요로하지 않을 때 주위를 지키는 것은 다른 문제입니다.

첫째, 종료시 모든 개체와 메모리가 해제됩니다. 누수가있는 경우 valgrind는이를 객체 등이 참조하지 않는 메모리로 감지합니다. 그러나 누출은 결국 운영 체제에 의해 해제됩니다.

예외 (...)를 모두 잡는 중이고 아무 것도하지 않으면 잘하지 마십시오. 그것은 일반적인 원인입니다.

둘째, 종료 중에 호출되는 소멸자의 로그 파일이 유용 할 수 있습니다. 아마도 main()의 끝에서 전역 플래그를 설정하십시오. 플래그가 설정되어있는 동안 호출 된 소멸자는 모두 존재한다고 출력 할 수 있습니다. 없어야 할 오브젝트가 많이 있는지 확인하십시오.

좀 더 쉽게, 전역 변수를 사용할 수 있으며, 각 ctor는 1 씩 증가시킬 수 있고 dtor는 1 씩 감소시킬 수 있습니다. 객체 수가 상대적으로 동일하지 않다는 것을 알게되면, 유사한 기술을 사용하여 문제를 만들고 있습니다.

셋째, Boost와 그 범위가 지정된 스마트 포인터를 사용하면 도움이되지만, 스마트 포인터를 성배로 사용하지 마십시오.

발생할 수있는 근본적인 문제가 있습니다. 장기 실행 프로그램의 경우 메모리 조각화로 인해 많은 메모리가 사용됩니다. 1MB 객체를 삭제 한 다음 2MB 객체를 만들려고 시도 할 수 있습니다. 1MB의 '자유 덩어리'가 충분히 크지 않기 때문에 창조는 새로운 공간에있을 것입니다. 그런 다음 512kb 객체를 만들면 1MB 객체의 공간으로 갈 수 있습니다. 사용 가능한 공간의 1/2 만 사용하고 다음 1MB 객체를 큰 공간에 할당해야합니다.

불행히도이 문제는 영구적 인 장소에 작은 물체가 할당되어 나빠질 수 있습니다. 예를 들어, 메모리에 300kb 떨어진 50 바이트 클래스가있을 수 있으며 그 중 100 비트처럼 512kb 객체는 할당 할 수 없기 때문에 새로운 객체마다 512kb를 추가로 할당하여 실제로 ' 여유 공간 '을 확보 할 수 있습니다.

이 문제는 확실한 원인으로 추적하기가 어렵지만 프로그램의 흐름을 살펴보면 작은 할당을 찾습니다. std :: list/vector/등을 기억하십시오. 이 모든 원인이 될 수 있습니다. 몇 주 동안 많은 메모리 작업을하는 데몬을 만들려는 경우 reserve()를 사용하여 메모리를 미리 할당하는 것이 좋습니다. 메모리 풀이 더 좋습니다.

넣을 시간에 따라 종료 할 때 개체에 대해보고하는 사용자 지정 메모리 할당자를 만들거나 찾을 수도 있습니다.

1

확실하기 때문에 메모리 누수가 없으므로 프로그램에서 메모리를 할당하고 누설없이 데이터를 저장하고있을 수 있습니다.

예를 들어, ...의이 프로그램이 링크 된 목록을 사용하여 말을

struct list{ 
DATA_ARRAY arr; //Some data 
struct *list next; 
}; 

While(true) //infinite loop 
{ 
// Add new nodes to list 
// Store some data in the node 
} 

여기에는 누수가 없습니다 보자. 그러나 루프는 새로운 노드를 영원히 추가하고 데이터를 저장하며 모든 것이 완벽하게 유효합니다. 그러나 메모리 사용은 항상 증가합니다. 당신이 2-5 일 동안 달리기 때문에, 이와 같은 것은 확실히 가능합니다.

더 이상 필요하지 않은 경우 코드 및 메모리를 검사해야 할 수도 있습니다.

3

Valgrind Massif 도구를 사용해보십시오. Massif manual에서 : 또한

, 같은 Memcheck의 같은 전통 누출 검사기에 의해 검출되지 않는 특정 공간 누수가있다. 메모리가 실제로 손실되지는 않기 때문에 포인터가 남아 있지만 사용하지 않는 것은 입니다. 이와 같은 누수가있는 프로그램은 불필요하게 시간이 지남에 따라 사용중인 메모리 양을 늘릴 수 있습니다. 대산 괴 은 이러한 누출을 식별하는 데 도움이됩니다.

대용량 저장 장치는 메모리가있는 상태와 메모리가 할당 된 상태 및 종료 될 때까지 해제되지 않는 위치를 보여줘야합니다.