Я только что написал некоторый многопоточный код, который обрабатывает огромные объекты.Даже когда я очищаю все от объекта (не удаляя его), он продолжает поглощать ГБ ОЗУ.К вашему сведению, я воспроизвел проблему в меньшей среде.
Этот код создает структуру и объект, содержащий вектор указателей на структуру.Затем я заполняю объект некоторыми указателями на структуру (созданную с помощью new).Я полагаю, что объект должен иметь только размер указателей, а не размер всех заостренных структур, но когда я запускаю код, размер объекта использует 300 МБ.
Когда я удаляю все элементывектор, а затем очистить вектор, память занята (но не используется сейчас) остается высокой.Кажется, что единственный способ освободить эту память - удалить весь объект, содержащий вектор.Почему вектор так много занимает ОЗУ, если он был только вектором указателя?Как я могу освободить его без необходимости удалять и заново создавать объект?
function -> void f_create_heapCleaner_string
создает строку, а затем удаляет ее.Иногда куча очищается с помощью этого трюка.
#include <string>
#include <malloc.h>
#include <vector>
#include <iostream>
using namespace std;
struct struct_test_struct {
string s_internal_data;
};
struct struct_test_struct* BASEDATA_struct_test_struct;
class objhandle_TestStruct__class {
public:
vector<struct struct_test_struct *> v_pointer_TestStruct;
unsigned int ui_v_size;
objhandle_TestStruct__class() {
ui_v_size = 3000;
}
void f_create_heapCleaner_string() {
string * s_tmp = new string();
(*s_tmp).assign(1000000, '*');
(*s_tmp) = "";
delete s_tmp;
}
void f_create_vector(unsigned int ui_size_str) {
cout << " f_create_vector() start " << endl;
malloc_stats();
for (unsigned int ui = 0; ui < ui_v_size; ui++) {
struct struct_test_struct * tmp_newstruct = new struct_test_struct();
(*tmp_newstruct).s_internal_data.assign((ui_size_str + ui), '*');
v_pointer_TestStruct.push_back(tmp_newstruct);
}
cout << " f_create_vector() end " << endl;
malloc_stats();
}
void f_delete_vector_content() {
cout << " f_delete_vector_content() start " << endl;
malloc_stats();
for (unsigned int ui = 0; ui < ui_v_size; ui++) {
delete v_pointer_TestStruct[ui];
}
f_create_heapCleaner_string();
cout << " f_delete_vector_content() end " << endl;
malloc_stats();
}
void f_clear_vector() {
cout << " f_clear_vector() start " << endl;
malloc_stats();
v_pointer_TestStruct.clear();
f_create_heapCleaner_string();
cout << " f_clear_vector() end " << endl;
malloc_stats();
}
void f_RUN_FULL_TEST(unsigned int ui_size_str) {
cout << " .... start test with string size of = " << ui_size_str << endl;
f_create_vector(ui_size_str);
f_delete_vector_content();
f_clear_vector();
}
};
int main(int argc, char**argv) {
objhandle_TestStruct__class * ptr_objhandle_TestStruct__class = new objhandle_TestStruct__class();
(*ptr_objhandle_TestStruct__class).f_RUN_FULL_TEST(100000);
(*ptr_objhandle_TestStruct__class).f_RUN_FULL_TEST(10000);
cout << " DELETE OBJECT start " << endl;
malloc_stats();
delete ptr_objhandle_TestStruct__class;
cout << " DELETE OBJECT finished " << endl;
malloc_stats();
return 0;
}
--- скомпилировать с: g ++ -oa test.cc
затем ./a
Вывод:
.... start test with string size of = 100000
f_create_vector() start
Arena 0:
system bytes = 135168
in use bytes = 48
Total (incl. mmap):
system bytes = 135168
in use bytes = 48
max mmap regions = 0
max mmap bytes = 0
f_create_vector() end
Arena 0:
system bytes = 309997568
in use bytes = 309972064
Total (incl. mmap):
system bytes = 309997568
in use bytes = 309972064
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() start
Arena 0:
system bytes = 309997568
in use bytes = 309972064
Total (incl. mmap):
system bytes = 309997568
in use bytes = 309972064
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() end
Arena 0:
system bytes = 309997568
in use bytes = 32832
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() start
Arena 0:
system bytes = 309997568
in use bytes = 32832
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() end
Arena 0:
system bytes = 309997568
in use bytes = 32832
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
.... start test with string size of = 10000
f_create_vector() start
Arena 0:
system bytes = 309997568
in use bytes = 32832
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
f_create_vector() end
Arena 0:
system bytes = 309997568
in use bytes = 40094656
Total (incl. mmap):
system bytes = 309997568
in use bytes = 40094656
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() start
Arena 0:
system bytes = 309997568
in use bytes = 40094656
Total (incl. mmap):
system bytes = 309997568
in use bytes = 40094656
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() end
Arena 0:
system bytes = 250077184
in use bytes = 32832
Total (incl. mmap):
system bytes = 250077184
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() start
Arena 0:
system bytes = 250077184
in use bytes = 32832
Total (incl. mmap):
system bytes = 250077184
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() end
Arena 0:
system bytes = 250077184
in use bytes = 32832
Total (incl. mmap):
system bytes = 250077184
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
DELETE OBJECT start
Arena 0:
system bytes = 250077184
in use bytes = 32832
Total (incl. mmap):
system bytes = 250077184
in use bytes = 32832
max mmap regions = 0
max mmap bytes = 0
DELETE OBJECT finished
Arena 0:
system bytes = 135168
in use bytes = 0
Total (incl. mmap):
system bytes = 135168
in use bytes = 0
max mmap regions = 0
max mmap bytes = 0
Спасибо, Франческо
-------------- Редактировать используя и объектный контейнер между объектом и структурой, это освободит память при удалении.. struct struct_test_struct {string s_internal_data;};
class objstruct_test_struct_OWNER {
public:
vector<struct struct_test_struct *> v_pointer_TestStruct;
};
class objhandle_TestStruct__class {
public:
class objstruct_test_struct_OWNER * ptr_OBJ;
unsigned int ui_v_size;
objhandle_TestStruct__class() {
ui_v_size = 3000;
}
.........
void f_create_vector(unsigned int ui_size_str) {
.....
ptr_OBJ = new objstruct_test_struct_OWNER();
cout << " f_create_vector() start " << endl;
malloc_stats();
for (unsigned int ui = 0; ui < ui_v_size; ui++) {
struct struct_test_struct * tmp_newstruct = new struct_test_struct();
(*tmp_newstruct).s_internal_data.assign((ui_size_str + ui), '*');
(*ptr_OBJ).v_pointer_TestStruct.push_back(tmp_newstruct);
}
.........
void f_clear_vector() {
.........
delete ptr_OBJ;
.........
таким образом, программа работает, это вывод
.... start test with string size of = 100000
f_create_vector() start
Arena 0:
system bytes = 135168
in use bytes = 64
Total (incl. mmap):
system bytes = 135168
in use bytes = 64
max mmap regions = 0
max mmap bytes = 0
f_create_vector() end
Arena 0:
system bytes = 309997568
in use bytes = 309972080
Total (incl. mmap):
system bytes = 309997568
in use bytes = 309972080
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() start
Arena 0:
system bytes = 309997568
in use bytes = 309972080
Total (incl. mmap):
system bytes = 309997568
in use bytes = 309972080
max mmap regions = 0
max mmap bytes = 0
f_delete_vector_content() end
Arena 0:
system bytes = 309997568
in use bytes = 32848
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32848
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() start
Arena 0:
system bytes = 309997568
in use bytes = 32848
Total (incl. mmap):
system bytes = 309997568
in use bytes = 32848
max mmap regions = 0
max mmap bytes = 0
f_clear_vector() end
Arena 0:
system bytes = 135168
in use bytes = 32
Total (incl. mmap):
system bytes = 135168
in use bytes = 32
max mmap regions = 1
max mmap bytes = 1007616
.... start test with string size of = 10000
f_create_vector() start
Arena 0:
system bytes = 135168
in use bytes = 64
Total (incl. mmap):
system bytes = 135168
in use bytes = 64
max mmap regions = 1
max mmap bytes = 1007616
f_create_vector() end
Arena 0:
system bytes = 40161280
in use bytes = 40094816
Total (incl. mmap):
system bytes = 40161280
in use bytes = 40094816
max mmap regions = 1
max mmap bytes = 1007616
f_delete_vector_content() start
Arena 0:
system bytes = 40161280
in use bytes = 40094816
Total (incl. mmap):
system bytes = 40161280
in use bytes = 40094816
max mmap regions = 1
max mmap bytes = 1007616
f_delete_vector_content() end
Arena 0:
system bytes = 40161280
in use bytes = 32848
Total (incl. mmap):
system bytes = 40161280
in use bytes = 32848
max mmap regions = 1
max mmap bytes = 1007616
f_clear_vector() start
Arena 0:
system bytes = 40161280
in use bytes = 32848
Total (incl. mmap):
system bytes = 40161280
in use bytes = 32848
max mmap regions = 1
max mmap bytes = 1007616
f_clear_vector() end
Arena 0:
system bytes = 1138688
in use bytes = 32
Total (incl. mmap):
system bytes = 1138688
in use bytes = 32
max mmap regions = 1
max mmap bytes = 1007616
DELETE OBJECT start
Arena 0:
system bytes = 1138688
in use bytes = 32
Total (incl. mmap):
system bytes = 1138688
in use bytes = 32
max mmap regions = 1
max mmap bytes = 1007616
DELETE OBJECT finished
Arena 0:
system bytes = 1138688
in use bytes = 0
Total (incl. mmap):
system bytes = 1138688
in use bytes = 0
max mmap regions = 1
max mmap bytes = 1007616
моя проблема, которую я только здесь показываю, заключается в том, что объекты, кажется, сохраняют выделенную память для себядо тех пор, пока они не будут удалены, поэтому кажется, что единственный способ освободить память для моего устройства - поместить данные в другой подобъект и удалить их ..
------------------- наконец .. я обнаружил, что когда программа хранит часть памяти, отображаемой для будущего использования, она используется повторно, как мы все знаем, и это нормально .. проблема в моей многопоточной программе заключалась в том, что malloc createэти "Arenas" и когда 2 malloc вызываются в один и тот же момент внутри большого объекта malloc, создайте еще одну "Arena", зарезервировав для нее новую карту памяти .. в моей программе у меня наконец-то нет свободного барана с 4 "Arenas"сопоставив более 3 ГБ оперативной памяти каждый, но реально используя менее 100 МБ каждый!поэтому проблема заключалась в отображении памяти (невозможно освободить вручную) и потоковом доступе к памяти, который умножает этот неиспользуемый ОЗУ на эти «арены», поэтому я создаю mutex_lock для всех потоков при доступе к этим объектам, чтобы они сохранялисьта же самая арена без «траты» памяти (отображенной, но не использованной) на несколько арен ..
я надеюсь, что немного объяснил мою проблему и решение .. надеюсь, что это может помочь кому-то еще;) еще раз спасибо, Франческо
----- я все еще тестирую .. я также видел это http://google -perftools.googlecode.com / svn / trunk / doc / tcmalloc.html они точно говорятв чем моя проблема .. "В ptmalloc2 память никогда не может перемещаться с одной арены на другую. Это может привести к огромным потерям пространства." и создать другой распределитель памяти, который должен помочь ..