메모리 누수가있는 오픈 소스 라이브러리에서 작업 중입니다. 라이브러리는 boost :: asio 주변에 구축 된 데이터 스트리밍 서비스입니다. 서버 측은 heap 메모리 관리 시스템을 사용하여 tcp 연결을 통해 밀어 넣기를 기다리는 동안 samples
의 유한 번호를 보유하는 메모리를 제공합니다. 서버가 처음 구성 될 때 모든 이전 sample
에 대한 메모리 힙이 할당됩니다. 이 힙에서 sample
이 소켓을 지나면 메모리가 힙으로 반환됩니다.새로운 (새로운 [])로 인한 메모리 누수를 방지
이미 할당 된 힙이 모두 사용되지 않는 한 괜찮습니다.
sample_p new_sample(double timestamp, bool pushthrough) {
sample *result = pop_freelist();
if (!result){
result = new(new char[sample_size_]) sample(fmt_, num_chans_, this);
}
return sample_p(result);
}
sample_p
sample
클래스에 템플릿 단지 typedef되어 스마트 포인터입니다 : 여기에 '샘플'을 생성하는 기능입니다.
중간에 문제가되는 줄이 있습니다. freelist
에 메모리 덩어리가 없으면 몇 가지를 만들어야합니다. 이 메모리 누수.
제 질문은 왜 이런 일입니까? 새 샘플을 스마트 포인터로 밀어 넣기 때문에 범위를 벗어날 때 메모리가 해제되어서는 안됩니다 (나중에 스택이 튀어 나옵니다). 내부적으로 할당 된 메모리를 어떻게 든 처리해야합니까? new char[sample_size_]
에 의해 할당 된 메모리? 그렇다면 어떻게 할 수 있습니까?
편집 : @RichardHodges는 컴파일 가능한 MCVE입니다. 이는 매우 단순화되었지만 원본 코드에서 직면 한 문제를 정확히 파악한다고 생각합니다.
#include <boost/intrusive_ptr.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
typedef boost::intrusive_ptr<class sample> sample_p;
typedef boost::lockfree::spsc_queue<sample_p> buffer;
class sample {
public:
double data;
class factory{
public:
friend class sample;
sample_p new_sample(int size, double data) {
sample* result = new(new char[size]) sample(data);
return sample_p(result);
}
};
sample(double d) {
data = d;
}
void operator delete(void *x) {
delete[](char*)x;
}
/// Increment ref count.
friend void intrusive_ptr_add_ref(sample *s) {
}
/// Decrement ref count and reclaim if unreferenced.
friend void intrusive_ptr_release(sample *s) {
}
};
void push_sample(buffer &buff, const sample_p &samp) {
while (!buff.push(samp)) {
sample_p dummy;
buff.pop(dummy);
}
}
int main(void){
buffer buff(1);
sample::factory factory_;
for (int i = 0; i < 10; i++)
push_sample(buff, factory_.new_sample(100,0.0));
std::cout << "press any key to exit" << std::endl;
char foo;
std::cin >> foo;
return 0;
}
코드를 단계별로 살펴보면 삭제 연산자가 샘플 포인터에서 호출되지 않는다는 것을 알 수 있습니다. 내가 작업하고있는 라이브러리 (다시 쓰지는 않았으므로 여전히 그 방법을 배우고있는 라이브러리)가 intrusive_ptr 유형을 잘못 사용하고있는 것 같습니다.
스마트 포인터 유형을 표시하지 않았습니다. –
의심되는 것으로 의심됩니다. 컴파일 할 수있는 MCVE를 게시 할 수 있습니까? –
@RichardHodges가 월요일에 올 것입니다. – dmedine