문제

C ++의 응용 프로그램에서 boost :: shared_ptr을 사용합니다. 메모리 문제는 실제로 심각하며 응용 프로그램은 많은 양의 메모리를 취합니다.

그러나 모든 새로운 객체를 shared_ptr에 넣기 때문에 응용 프로그램이 종료되면 메모리 누출을 감지 할 수 없습니다.

같은 것이 있어야합니다 std::vector<shared_ptr<> > 자원을 보유하고있는 수영장. 디버깅 할 때 누가 shared_ptr을 보유하고 있는지 어떻게 알 수 있습니까?

코드를 라인별로 검토하기는 어렵습니다. 너무 많은 코드 ...

매우 감사합니다!

도움이 되었습니까?

해결책

당신은 a를 보면 알 수 없습니다 shared_ptr, "형제 포인터"가있는 곳. 당신은 하나인지 테스트 할 수 있습니다 unique() 또는 얻으십시오 use_count(), 의 사이에 다른 방법.

다른 팁

shared_ptr의 대중적인 광범위한 사용은 필연적으로 원치 않는, 보이지 않는 메모리 점령을 유발할 것입니다.

주기적 참조는 잘 알려진 원인이며 일부는 간접적이고 특히 하나 이상의 프로그래머가 수행하는 복잡한 코드에서 발견하기가 어려울 수 있습니다. 프로그래머는 한 객체가 빠른 수정으로 다른 객체에 대한 참조가 필요하다고 결정할 수 있으며 모든 코드를 검사하여 사이클을 닫고 있는지 확인할 시간이 없습니다. 이 위험은 크게 과소 평가되었습니다.

덜 잘 이해되지 않은 참고 문헌의 문제는 잘 이해되지 않습니다. 객체가 많은 shared_ptrs와 공유되면 각각의 객체가 제로화되거나 범위를 벗어날 때까지 파괴되지 않습니다. 이러한 참조 중 하나를 간과하고 끝났다고 생각한 기억에 숨어있는 물체로 끝나는 것은 매우 쉽습니다.

엄격하게 말하지만 이것들은 메모리 누출이 아니지만 (프로그램이 종료되기 전에 모두 풀릴 것입니다) 그들은 해롭고 탐지하기가 더 어렵습니다.

이러한 문제는 편리한 허위 선언의 결과입니다. 1. shared_ptr로 단일 소유권이되고 싶은 것을 선언합니다. scoped_ptr는 정확하지만 해당 객체에 대한 다른 언급은 원시 포인터 여야하며, 이는 매달려있을 수 있습니다. 2. Shared_ptr과 같은 수동적 관찰 참조가되고 싶은 것을 정말로 선언합니다. 약한 _ptr은 정확하지만 사용할 때마다 share_ptr로 변환하는 번거 로움이 있습니다.

나는 당신의 프로젝트 가이 관행이 당신을 얻을 수있는 문제의 종류의 훌륭한 예라고 생각합니다.

메모리 집중 애플리케이션이있는 경우 디자인이 객체 수명을 명시 적으로 제어 할 수 있도록 단일 소유권이 필요합니다.

단일 소유권 OpObject = null; 객체를 확실히 삭제하면 이제 그렇게 할 것입니다.

공유 소유권으로 spobject = null; ........누가 알아?......

우리가 수행 한 매달려 있거나 원형 스마트 포인터 참조에 대한 한 가지 솔루션은 스마트 포인터 클래스를 사용자 정의하여 디버그 전용 부기 기능을 추가하는 것입니다. SmartPointer가 객체에 대한 참조를 추가 할 때마다 스택 추적이 필요하고 각 항목을 추적하는지도에 넣습니다.

  1. 할당되는 물체의 주소 (포인터가 가리키는 것)
  2. 개체에 대한 참조를 보유한 각 SmartPointer 객체의 주소
  3. 각 스마트 포인터가 구성되었을 때의 해당 스택 트레이스

SmartPointer가 범위를 벗어나면지도의 항목이 삭제됩니다. 객체에 대한 마지막 스마트 포인터가 파괴되면 Pointee 객체가 맵의 항목을 제거합니다.

그런 다음 두 가지 함수가 포함 된 "트랙 누출"명령이 있습니다. '누출 추적 시작'명령이 발행 된 이후. 스마트 포인터가 어디에 왔는지 스택 흔적을 볼 수 있기 때문에, 당신은 당신의 물체가 해방되는지에 대한 사람을 쉽게 알 수 있습니다. 켜져있을 때 물건이 느려집니다. 그래서 우리는 항상 그것을 떠나지 않습니다.

구현하는 것은 상당한 양의 작업이지만, 이런 일이 많이 발생하는 코드베이스가 있다면 그만한 가치가 있습니다.

사이클을 통해 공유 포인터 메모리 누출이 발생할 수 있습니다. 공유 객체는 결국 원본으로 다시 이어지는 다른 공유 객체에 대한 참조를 보유 할 수 있습니다. 이런 일이 발생하면 사이클은 다른 사람이 객체에 액세스 할 수 없더라도 모든 참조 수를 1로 유지합니다. 해결책은입니다 약한 포인터.

일부 장소에서 공유 포인터 대신 약한 포인터를 사용하여 소유권이 더 명시 적으로 표현되도록 코드의 일부 리팩토링을 시도하십시오.

클래스 계층 구조를 볼 때 어떤 클래스가 실제로 공유 포인터를 보유 해야하는지, 약한 포인터 만 필요한 클래스를 결정할 수 있으므로 "실제"소유자 객체가 없으면주기를 피할 수 있습니다. 소유자 "개체는 이미 사라 졌을 것입니다. 일부 객체가 포인터를 너무 일찍 잃어버린 것으로 밝혀지면 앱에서 객체 파괴 시퀀스를 살펴보고 수정해야합니다.

당신은 분명히 응용 프로그램 내에서 객체에 대한 참조를 보유하고 있습니다. 이것은 당신이 의도적으로 물건을 기억에두고 있음을 의미합니다. 즉, 메모리 누출이 없습니다. 메모리 누출은 메모리가 할당 된 후 주소를 참조하지 않습니다.

기본적으로 디자인을보고 왜 많은 객체와 데이터를 메모리에 보관하는지 알아 내고 어떻게 최소화 할 수 있는지 알아 내야합니다.

의사-메모리 누출이있을 가능성은 자신이 생각하는 것보다 더 많은 물체를 만들고 있다는 것입니다. '신규'가 포함 된 모든 진술에 중단 점을 넣으십시오. 응용 프로그램이 생각했던 것보다 더 많은 객체를 구성하는지 확인한 다음 해당 코드를 읽으십시오.

문제는 응용 프로그램 디자인의 문제인 것만 큼 메모리 누출이 아닙니다.

당신이 창문에 있다면 umdh를 사용하는 것이 좋습니다. 매우 강력한 도구입니다. 사용하여 해방 될 것으로 예상되는 트랜잭션/시간 기간당 할당을 찾은 다음 누가 보유하고 있는지 찾으십시오.

이에 대한 답변에 대한 자세한 정보가 있습니다스마트 포인터로 인한 메모리 누출을 찾으십시오

프로그램 내에서 어떤 개체가 Shared_ptr 자신이 자신의 공유를 말할 수 없습니다. Linux에 있다면 메모리 누출을 디버깅하는 한 가지 확실한 방법은 다음과 같습니다. Valgrind 도구 - 질문에 직접 답변하지는 않지만 메모리가 어디에 할당되었는지 알려줍니다. 이는 일반적으로 문제를 해결하기에 충분합니다. Windows가 비슷한 도구를 가지고 있다고 생각하지만 어느 것이 가장 좋은지 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top