다음 코드는 내 데비안 시스템에서 이상한 메모리 동작을 유발합니다. 지도가 지워진 후에도 htop은 프로그램이 여전히 많은 메모리를 사용하고 있음을 보여 주므로 메모리 누수가 있다고 생각합니다. 이상한 사실은 그것이 일부 상황에서만 나타납니다.std map 및 shared_ptr을 사용한 이상한 메모리 동작
#include <map>
#include <iostream>
#include <memory>
int main(int argc, char** argv)
{
if (argc != 2)
{
std::cout << "Usage: " << argv[0] << " <1|0> " << std::endl;
std::cout << "1 to insert in the second map and see the problem "
"and 0 to not insert" << std::endl;
return 0;
}
bool insertion = atoi(argv[1]);
std::map<uint64_t, std::shared_ptr<std::string> > mapStd;
std::map<uint64_t, size_t> counterToSize;
size_t dataSize = 1024*1024;
uint64_t counter = 0;
while(counter < 10000)
{
std::shared_ptr<std::string> stringPtr =
std::make_shared<std::string>(dataSize, 'a');
mapStd[counter] = stringPtr;
if (insertion)
{
counterToSize[counter] = dataSize;
}
if (counter > 500)
{
mapStd.erase(mapStd.begin());
}
std::cout << "\rInserted chunk " << counter << std::flush;
counter++;
}
std::cout << std::endl << "Press ENTER to delete the maps" << std::endl;
char a;
std::cin.get(a); // wait for ENTER to be pressed
mapStd.clear(); // clear both maps
counterToSize.clear();
std::cout << "Press ENTER to exit the program" << std::endl;
std::cin.get(a); // wait for ENTER to be pressed
return 0;
}
설명 :
코드는 스택에 두 개의 맵을 생성한다 (그러나이 힙에 생성되는 경우 문제가 동일합니다). 그런 다음 문자열의 std :: shared_ptr을 첫 번째 맵에 삽입합니다. 각 문자열의 크기는 1MB입니다. 500 개의 문자열이 삽입되면 새로운 삽입마다 첫 번째 문자열을 삭제하므로지도에 사용 된 총 메모리는 항상 500MB와 같습니다. 총 10000 개의 문자열이 삽입되면 프로그램은 사용자가 Enter 키를 누를 때까지 기다립니다. 프로그램을 실행하고 첫 번째 인수로 1을 전달하면 첫 번째 맵에 삽입 될 때마다 두 번째 맵에도 다른 삽입이 수행됩니다. 첫 번째 인수가 0이면 두 번째 맵은 사용되지 않습니다. 일단 ENTER를 누르면 두 맵이 모두 지워집니다. 프로그램이 계속 실행되고 ENTER 키를 다시 기다린 다음 종료합니다. 후 (맵이 지워집니다 따라서 후)을 누르면 ENTER 내 64 비트 데비안 3.2.54-2에
때, 그리고 프로그램이 함께 시작됩니다 : 여기
는 사실이다 1을 첫 번째 인수로 (따라서 두 번째 맵에 삽입하여) htop은 프로그램이 여전히 500MB의 메모리를 사용함을 나타냅니다! 프로그램이 첫 번째 인수로 0으로 시작되면 메모리가 올바르게 해제됩니다.
이 기계는 g ++ 4.7.2 및 libstdC++. so.6.0.17을 사용합니다. 나는 g ++ 4.8.2와 libstdC++, so.6.0.18, 같은 문제를 시도했다.
- 저는 g ++ 4.9.2와 libstdC++. so.6.0.20, 같은 문제로 64 비트 페도라 21을 시험해 보았습니다.
- 32 비트 g ++ 4.8.2 및 libstdC++. so.6.0.19의 우분투 14.04를 사용해 보았습니다. 문제가 나타나지 않습니다!
- 32 비트 g ++ 4.7.2 및 libstdC++. so.6.0.17을 사용하는 Debian 3.2.54-2를 시도했지만 문제가 나타나지 않습니다!
- 64 비트 Windows에서 시도했지만 문제가 나타나지 않습니다! 문제는 당신이지도 지워 줄을 (반전 경우 명확한 먼저 uint64_t는,이 size_t지도, 문제가 사라질 경우에 따라서!
누군가는 모든 설명이 있습니까, 존재하는 시스템에서
메모리 할당자는 C++ 표준 라이브러리에 의해 구현되며 gcc는 libc의'malloc'을 사용합니다. 또한 각 테스트 머신에서 사용중인 libc 버전을 포함시켜야합니다. Windows는 컴파일러에 따라 자체적으로 완전히 다른 구현을 가지고 있습니다. –
참조 http://unix.stackexchange.com/questions/53447/does-free-unmap-the-memory-of-a-process, http://stackoverflow.com/questions/14023815/memory-stability-of -ac-application-in-linux, http://stackoverflow.com/questions/13232119/memory-usage-doesnt-decrease-when-free-used, http://stackoverflow.com/questions/1119134/how-do -malloc-and-free-work – nos