LinuxForum.Fans
Тема

Что с памятью?

Автор: rip86oz 20 сообщений 4275 просмотров
#65851

Резервирую под изображение память (от 100 кб до 200 Мб), через new[_datalen_].
После получения картинки идёт обработка и сохранение, а потом delete[]. Тут ничего особого.

Если производить данную процедуру один раз - странностей нет.
Однако при повторном выделении\освобождении, память остаётся занятой программой.

Например:
В 1-ом столбце указывается сколько занимает прога, во 2-ом - размер принятой картинки, далее опять в 1-ом столбце указывается сколько занимает прога, но уже после освобождения памяти для картинки.
(Мб)
Программа, Изображение
1,5
30
1,7
33,8
1,8
61,5
1,9
1,5
2,9
15,3
17,0

Видно, что если начать принимать изображения с меньшим размером, чем были до этого, то память перестаёт освобождаться. Думается, что это наподобие кеширования что-то, или особенности работы менеджера памяти. х3. Что это такое может быть и как это исправить? подразумевается, что прога будет в трее висеть, но с набалдашниками в десятки метров - перебор.

#65857

Исходники покажите, без них - стрельба семечками по воробьям.

в 1-ом столбце указывается сколько занимает прога

Как определяте?

#65863
AndreyMust19 написал:

Как определяте?

KSysGuard
(В Gnome System Monitor почти тоже самое) smile

AndreyMust19 написал:
Исходники покажите, без них - стрельба семечками по воробьям.

Упрощенный путь массива с данными изображения:

text

...
unsigned char* csl_imagedata; // объявление
...
//начало рабочего цикла программы

csl_imagedata = new unsigned char[size];

int offset = 0 while (принимать данные) { // приём данных с утройства libusb_bulk_transfer (scnHandle, _epaddr, &(csl_imagedata[offset]), *datalength, &transferred, 3000); offset += transferred; //transferred - сколько данных принято. но с этим всё нормально }

delete[] csl_imagedata;

//конец рабочего цикла программы

Выделение памяти и приём данных идёт в другом потоке. Очистка вызывается в основном. Хотя это наврятли влияет, т.к. память всё-таки освобождается

#65890

Какую память смотрите? Вам нужна резидентная память, а не просто память.
Не думаю, что проблема какая-то страшная, зависит от того, какие файлы вы подаете программе на обработку. И про дисковый кеш не забудьте.
Исходники большие? Если нет, выложите полностью все. И приложите исполняемый файл (в случае если скомпилировать исходники будет проблематично).

#65929
AndreyMust19 написал:
Какую память смотрите? Вам нужна резидентная память, а не просто память.

Смотрю столбец VmRss - весь занимаемый объём физической памяти. Кажись это и есть резидентная.

AndreyMust19 написал:

Не думаю, что проблема какая-то страшная, зависит от того, какие файлы вы подаете программе на обработку. И про дисковый кеш не забудьте.
Исходники большие? Если нет, выложите полностью все. И приложите исполняемый файл (в случае если скомпилировать исходники будет проблематично).

Прога берёт данные со сканера, поэтому наврятли получится опробовать её. Если только написать нечто вроде эмуляции, но что-то желания делать это нет.
Исходники относительно большие. Вот куски, которые могут быть интересны, в отношении проблемы:

text

int TcanonScanLide70::cleardata() { pthread_mutex_lock(&imagescan_mutex); int complete = complete_thread; pthread_mutex_unlock(&imagescan_mutex); cout << "call data clear..."; if (not csl_imageempty) { if (complete != 0) { printf("cleaned at ptr = %p\n",csl_imagedata); delete[] csl_imagedata; csl_imagedata = NULL; csl_imageempty = true; imagewidth_req = 0; csl_datalength = 0; csl_imagewidth = 0; csl_imageheight = 0; imagebpp = 0; return 0; } else { cout << "not allow, scanner is reading\n"; return -2; } } else { cout << "there no data\n"; return -1; } };

...

int TcanonScanLide70::allocimgdata(int size) { csl_imagedata = new unsigned char[size]; csl_imageempty = false; printf("alloc image data, length = %d bytes at ptr = %p\n",size,csl_imagedata); };

...

int TcanonScanLide70::doscan(int dpi,int bpp, int x,int y,int w,int h) { if (readbuttons() > -1) { pthread_mutex_lock(&imagescan_mutex); int complete = complete_thread; pthread_mutex_unlock(&imagescan_mutex); if ((complete == 5) or (complete == 16)) { if (x+w > maximagewidth(dpi)) { cout << "Can`t start scan. Too high image width: " << x << "(x) + " << w << "(w) = " << x+w << " > " << maximagewidth(dpi) << "\n"; return -2; } if (y+h > maximageheight(dpi)) { cout << "Can`t start scan. Too high image height: " << y << "(y) + " << h << "(h) = " << y+h << " > " << maximageheight(dpi) << "\n"; return -3; } if (x < 0) { cout << "Can`t start scan. X offset less zero\n"; return -4; } if (y < 0) { cout << "Can`t start scan. Y offset less zero\n"; return -5; } if (w < 1) { cout << "Can`t start scan. Image width less 1\n"; return -6; } if (h < 1) { cout << "Can`t start scan. Image height less 1\n"; return -7; } cout << "\nstart scanning\n\n"; cleardata(); int realw = ((w * 600 / dpi ) | 0x7f) * dpi / 600 + 1; int memalloc = realw*h*bpp/8; if (memalloc < 2000000) memalloc = 2000000; allocimgdata(memalloc); imagewidth_req = w; imageheight_req = h;

csl_datalength = 0; imagedatalength_thread = 0;

complete_thread = 0;

scanparams params(this,dpi,bpp,x,y,w,h);

pthread_create(&scanthread,NULL,doscanthread,&params); return 0; } else { cout << "\nCan`t start scan. Scanner is working\n\n"; return 1; } } else return -1; }

....

//ФУНКЦИЯ ГДЕ ПРИНИМАЮТСЯ ДАННЫЕ, РАБОТАЕТ В ДРУГОМ ПОТОКЕ.

int TcanonScanLide70::csl_rRAMdo() { int complete = 0; cout << " read scanner RAM\n"; int dpi = 0; unsigned char bpp = 6; unsigned char tregs[0xff]; csl_getallregs(tregs); //printregs(tregs); switch (tregs[0xb0]) { case 11: dpi = 75; break; case 10: dpi = 150; break; case 9 : dpi = 300; break; case 8 : dpi = 600; break; } if (tregs[0x01] == 29) bpp = 3; int finline = (getreg(0x66) << 16) + (getreg(0x67) << 8) + getreg(0x68); csl_imageheight = finline / 3; csl_imagewidth = ((getreg(0x0a) << 8) + getreg(0x0b) - (getreg(0x08) << 8) - getreg(0x09)) * dpi / 600 + 1; if (rRAMdo_image) { pthread_mutex_lock(&imagescan_mutex); imagewidth_thread = csl_imagewidth; pthread_mutex_unlock(&imagescan_mutex); } csl_datalength = 0; cout << " waiting for data: ";

int grcnt = 0; int datasize = 0; while (datasize == 0) { datasize = getreg(0xa5) << 16; datasize += getreg(0xa6) << 8; datasize += getreg(0xa7,get_delay_tx,14000); drawprocess((grcnt++ >> 3) & 0xf); pthread_mutex_lock(&imagescan_mutex); if (complete_thread == 10) { complete_thread = 2; complete = 10; }//*/ pthread_mutex_unlock(&imagescan_mutex); if (complete == 10) break; } if (complete == 10) { setreg(0x03,0x04); printf(" ...canseled\n"); while (getreg(0x46,300,100000) != 0) {}; return 0; } cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; fflush(stdout); datasize <<= 1; int datasizeread = 0; printf("work with dat at ptr = %p\n",csl_imagedata); printf(" reading data (total to read = %d): ",(imagebpp/8 * (csl_imagewidth+1) * csl_imageheight)); int imagedatasizeadd = 0; while (true) { if ((getreg(0x46) == 0) and (datasize == 0)) break; drawprocess((grcnt++ >> 3) & 0xf); //correcting datasize to scanner data reading rulez: size = xxx0 and < effo datasizeread = datasize; if (datasizeread > 0xeff0) datasizeread = 0xeff0; imagedatasizeadd = datasizeread; if ((datasizeread & 0xf) != 0) datasizeread= (datasizeread & 0xfff0) + 0x10; //----------------------------------------------------------------------- if (datasizeread > 0) csl_setdatasize(datasizeread); if (datasizeread > 0x200) { int datarxlen = datasizeread; int datarx_b_len = datarxlen; int bulksnum = 2; if ((datarx_b_len & 0x01ff) != 0) { datarx_b_len = (( datarxlen ) >> 9 ) << 9; bulksnum++; } unsigned char data0[4] = {5,0x70,(unsigned char) ((datarxlen) & 0xff),(unsigned char) ((datarxlen) >> 8)}; int res = bulkrun( 2, data0, 4, 300, -1); if (res != 0 ) return res-100;

res = bulkrun( 0x83, &(csl_imagedata[csl_datalength]), datarx_b_len, 300, -1); if (res != 0 ) return res-200; csl_datalength+=datarx_b_len; if (bulksnum > 2) { res = bulkrun( 0x83, &(csl_imagedata[csl_datalength]), 0x200, 300, -1); if (res != 0 ) return res-300; csl_datalength +=imagedatasizeadd- datarx_b_len; }

} else { if (datasizeread > 0) { dtrx[0] = 5; dtrx[1] = 0x70; dtrx[2] = (unsigned char) ((datasizeread) & 0xff); dtrx[3] = (unsigned char) ((datasizeread) >> 8); int res = bulkrun( 2, dtrx, 4, get_delay_tx, -1); if (res != 0) return res-500; int imgsget = 0x200; res = bulkrun( 0x83, &(csl_imagedata[csl_datalength]), &imgsget, 300, -1); if (res != 0) return res-600; csl_datalength += imagedatasizeadd; } }

if ( rRAMdo_image ) { pthread_mutex_lock(&imagescan_mutex); if (complete_thread == 10) { complete_thread = 2; complete = 10; } imagedatalength_thread = csl_datalength; pthread_mutex_unlock(&imagescan_mutex); } if (complete == 10) { setreg(0x03,0x04); printf(" ...canseled"); while (getreg(0x46,300,100000) != 0) {};

complete = 2; break; } datasize = getreg(0xa5,300) << 16; datasize += getreg(0xa6,300) << 8; datasize += getreg(0xa7,2000); datasize <<= 1; } printf("\n get %d bytes; finish\n",csl_datalength); return 0; };

// ФУНКЦИЯ В КОТОРУЮ ПЕРЕДАЁТСЯ csl_imagedata, как параметр data.

int TcanonScanLide70::bulkrun(unsigned char _epaddr, unsigned char *_data,int *_datalength, int _delay,int i) {

int transferred; int res;

res = libusb_bulk_transfer (TcanonScanLide70::TcanonScanLide70::scnHandle, _epaddr, _data, *_datalength, &transferred, 3000); if (_epaddr == 2) *_datalength = transferred;

switch (res) { case 0 : break; case LIBUSB_ERROR_TIMEOUT: printf("%d - error: LIBUSB_ERROR_TIMEOUT (the transfer timed out)",i); libusb_clear_halt(TcanonScanLide70::scnHandle,_epaddr); break; case LIBUSB_ERROR_PIPE: printf("%d - error: LIBUSB_ERROR_PIPE (the endpoint halted)",i); break; case LIBUSB_ERROR_OVERFLOW: printf("%d - error: LIBUSB_ERROR_OVERFLOW (the device offered more data)",i); break; case LIBUSB_ERROR_NO_DEVICE: printf("%d - error: LIBUSB_ERROR_NO_DEVICE (the device has been disconnected)",i); break; default: printf("%d - error: LIBUSB ERROR = %d",i,res); break; }

usleep(_delay);

return res; };

Вот лог который прога выдает - насчёт того что память должна нормально освобождаться.

text

...CanoScan Lide 70 init start

iProduct (?CanoScan)= CanoScan NumConfigurations (?1)= 1 scanner configured, Active config value = 1 MaxPower for active config (hex) = FA, (DEC) (?250)= 250 NumInterfaces for active config (?1)= 1 num_altsetting for interface 0 (?1)= 1 NumEndpoints (?2)= 2 EndPoint 1 address (?2 out EP-2)= 2 EndPoint 2 address (?83 in EP-3)= 83 ...CanoScan Lide 70 init finish alloc image data, length = 230686720 bytes at ptr = 0x7fe5b04fb010 call data clear...cleaned at ptr = 0x7fe5b04fb010 Initialization

start calibration

call data clear...there no data alloc image data, length = 2097152 bytes at ptr = 0x7fe5bdefb010 startmotor 15 93 startmotor 5 93 startmotor 5 d1 read scanner RAM work with data at ptr = 0x7fe5bdefb010 reading data (total to read = 0):' get 1959936 bytes; finish Rollback startmotor 5 35 call data clear...cleaned at ptr = 0x7fe5bdefb010 call data clear...there no data DPI (75,150,300,600): 600 BPP (24,48): 24 X offset: (0..5103): 0 Width: (1..5104): 5000 Y offset: (0..7001): 0 Height: (1..7002): 2000

start scanning

call data clear...there no data alloc image data, length = 30720000 bytes at ptr = 0x7fe5bc3af010 scan with params: DPI: 600, BPP: 24, L: 0069, Y: 0126, R: 1468, H: 1770 startmotor 15 93 startmotor 5 93 startmotor 15 d1 read scanner RAM work with data at ptr = 0x7fe5bc3af010 reading data (total to read = 384):` get 979968 bytes; finish next RAM read - image startmotor 5 91 read scanner RAM work with data at ptr = 0x7fe5bc3af010 reading data (total to read = 30726000):' get 30720000 bytes; finish Rollback call data clear...cleaned at ptr = 0x7fe5bc3af010 wait... startmotor 5 35 finish scanning want new scan? (y,s - scan, c - calibration): n

Attemp to close scanner connection

call data clear...there no data Scanner connection closed

Читал инет, говорят, что может быть фрагментация. Хотя всё равно не понимаю, почему именно в таком виде - т.е. когда выделяется память меньшего объема, чем в предыдущий раз.

ЗЫ. Когда производится калибровка, то сканер выдает 2 Мб данных (в массив изображения). После первой калибровки данные освобождаются. После второй нет (прога начинает занимать 2 метра с копейками физической памяти). Однако после 3,4 и т.п. калибровки память больше ни кушается - т.е. так и остаются висеть 2 Мб в проге.

#65972

Удалось частично решить проблему, за счёт выделения каждый раз по 220Мб (маскимально возможный объем изображения), вне зависимости от того какой объём реально потребуется для картинки. При этом физическая память потребляется как следует - выделяется столько, сколь данных пришло, а в виртуальной, как впрочем следовало, выделилось 220 Мб. После освобождения прога нагружается на несколько десятков килобайт - по видимому это связано с хранением виртуальных адресов. Одно сканирование 600dpi 24bpp добавляет около 100кб к занимаемой физической памяти. что в общем-то, не очень страшно, хотя избавится-бы от этого хотелось. Но это уже, как понимаю, надо давать какие-то указания ядру.

#66015

ЗЫ. Когда производится калибровка, то сканер выдает 2 Мб данных (в массив изображения). После первой калибровки данные освобождаются. После второй нет (прога начинает занимать 2 метра с копейками физической памяти). Однако после 3,4 и т.п. калибровки память больше ни кушается - т.е. так и остаются висеть 2 Мб в проге.

Тогда, думаю, у вас вот здесь гвоздь:

text
if (memalloc < 2000000) memalloc = 2000000;
allocimgdata(memalloc);
...
pthread_create(&scanthread,NULL,doscanthread,&params);
return 0;

Возможно, что создаваемые потоки освобождают свою память, а вот сама ф-я doscan освободить эти 2 МБ забывает после 1-ой калибровки, отсюда они и остаются в памяти. К сожалению, функции scanthread и doscanthread вы не показываете, поэтому на их счет ничего сказать не могу.

#66072

Уже это исправил. Действительно оказалось, что new[] не потокобезопасен и теперь выделение и освобождение памяти идёт в основном потоке. Однако проблема оставалась.

В функцию выделения памяти добавил строку, которая игнорирует передаваемое значение size и ставит его в 220 метров

text

int TcanonScanLide70::allocimgdata(int size)
{
    size = 220*1024*1024;
    csl_imagedata = new unsigned char[size];
    csl_imageempty = false;
    printf("alloc image data, length = %d bytes at ptr = %p\n",size,csl_imagedata);    
};

Результат - всё освобождается. Занимаемая виртуальная память растёт по мере её потреблений вплоть до 220 Мб. (т.е. если было принято 30 Мб данных картинки, то виртуальная память после освобождения так и остаётся 30 метров). Занимаемая физическая тоже растёт (килобайты) - видимо хранит нарастающее количество виртуальных адресов, для дальнейшего использования.
Теперь встаёт вопрос как освободить память выделенную для хранения виртуальных адресов.

#66077

Теперь встаёт вопрос как освободить память выделенную для хранения виртуальных адресов.

Никак, наверное. В Си++ нет сборщика мусора.

#66082

rip86oz,
А можно получить комментарии по поводу вот этого блока:

text
            delete[] csl_imagedata;
            csl_imagedata = NULL;
            csl_imageempty = true;
            imagewidth_req = 0;
            csl_datalength = 0;
            csl_imagewidth = 0;
            csl_imageheight = 0;
            imagebpp = 0;

?
Да и вообще интересует первая строка. Какой компайлер используете при компиляции такой конструкции и насколько Вы уверены, что при этом с компиляцией все ОК?

#66089
Hvzh написал:
rip86oz,
А можно получить комментарии по поводу вот этого блока:
text
            delete[] csl_imagedata;
            csl_imagedata = NULL;
            csl_imageempty = true;
            imagewidth_req = 0;
            csl_datalength = 0;
            csl_imagewidth = 0;
            csl_imageheight = 0;
            imagebpp = 0;

?
Да и вообще интересует первая строка. Какой компайлер используете при компиляции такой конструкции и насколько Вы уверены, что при этом с компиляцией все ОК?

g++. Комментарий - освобождаю выделенную память, далее в нуль ставлю указатель, а потом всё тоже по нулям
Более интересно - зачем завёл переменную csl_imageempty - для перестраховки, чтоб уж наверняка. smile

Вот makefile:

text

CFLAGSAPP = -O3

LOCPATH = /home/rip86oz/Programming/libcanonlide70

apptest: libcanonlide70.so apptest.o g++ $(CFLAGSAPP) -o apptest apptest.o -L. -lcanonlide70 -lpngwriter -lpng -lz -lfreetype -Wl,-rpath,$(LOCPATH) -lpngwriter apptest.o: apptest.cpp canonlide70.h g++ -c $(CFLAGSAPP) apptest.cpp -I/usr/include/freetype2

CFLAGSLIB = -fPIC -O3

libcanonlide70.so: canonlide70.o g++ -shared $(CFLAGSLIB) -o libcanonlide70.so canonlide70.o -L/usr/local/lib -lusb-1.0 -Wl,-rpath,$(LOCPATH)

canonlide70.o: canonlide70.cpp canonlide70.h libusb.h g++ -c -Wall $(CFLAGSLIB) canonlide70.cpp

clean: rm -f *.o libcanonlide70

Результат:
cd '/home/rip86oz/Programming/libcanonlide70/.' && LC_MESSAGES="C" LC_CTYPE="C" make -k
компиляция canonlide70.cpp (g++)
компоновка libcanonlide70.so (g++)
компиляция apptest.cpp (g++)
компоновка apptest (g++)
*** Успешное завершение ***

Кажись проблем нет.

AndreyMust19 написал:
Теперь встаёт вопрос как освободить память выделенную для хранения виртуальных адресов.

Никак, наверное. В Си++ нет сборщика мусора.

Ну и ладно. 400 кб, по сравнению с GUI в 3 Мб, не беда.

#66091

А попробуйте заменить эту строку

text
csl_imagedata = NULL;

такой

text
csl_imagedata = 0;

Чем черт не шутит?

#66119

Нет, если csl_imagedata - типа void * или просто любой указатель, то без разницы - 0 или NULL.
А вот тип csl_imagedata - число, то разница есть.

unsigned char* csl_imagedata;

Без разницы.

#66148
Hvzh написал:
А попробуйте заменить эту строку
text
csl_imagedata = NULL;

такой

text
csl_imagedata = 0;

Чем черт не шутит?

Увы, но чёрт не шутил. Что 0, что NULL. - без разницы.

Теперь однако-ж появилась другая фигня.
Для сохранения картинки в PNG формат с 48-и битной глубиной цвета использую pngwriter. Так вот он так-же начинает хавать память, а освобождать нет. Хотя в доках говорится, что по закрытии объекта вся память высвобождается.(Если не использовать pngwriter, и сканировать в холостую, то память не кушается. - т.е. проблема именно в использовании pngwriter).

вся прога, собственно (в вышеприведённом makefile - apptest):

text

#define NO_FREETYPE
#include <pngwriter.h>
 
#include <iostream>
#include "canonlide70.h"
using namespace std;

int main(int argc,char** argv) { char* apppath; int arg0l = strlen(argv[0]); int lastsl = 0; for(int i = 0 ; i < arg0l;i++) if (argv[0][i] == '/') lastsl = i;

apppath = new char[lastsl]; strncpy(apppath,argv[0],lastsl); TcanonScanLide70 scanner; if (scanner.init() < 0) { cout << "error CanoScan LiDE 70 initialization\n"; return -1; } while (scanner.getdata() == 0) {usleep(10000);} scanner.cleardata(); do { bool skipscan = false; int dpi = 75; int bpp = 24; int x = 0; int w = 1; int y = 0; int h = 1; cout << "DPI (75,150,300,600): "; fflush(stdout); cin >> dpi; if ((dpi != 75) and (dpi != 150) and (dpi != 300) and (dpi != 600)) skipscan = true; if (skipscan == true) goto skipquestslabel; cout << "BPP (24,48): "; fflush(stdout); cin >> bpp; if ((bpp != 24) and (bpp != 48)) skipscan = true; if (skipscan == true) goto skipquestslabel; cout << "X offset: (0.."<<scanner.maximagewidth(dpi)-1<<"): "; fflush(stdout); cin >> x; if ((x > scanner.maximagewidth(dpi)-1) or (x < 0)) skipscan = true; if (skipscan == true) goto skipquestslabel;

cout << "Width: (1.."<<scanner.maximagewidth(dpi)-x<<"): "; fflush(stdout); cin >> w; if ((w > scanner.maximagewidth(dpi)-x) or (w < 1)) skipscan = true; if (skipscan == true) goto skipquestslabel;

cout << "Y offset: (0.."<<scanner.maximageheight(dpi)-1<<"): "; fflush(stdout); cin >> y; if ((y > scanner.maximageheight(dpi)-1) or (y < 0)) skipscan = true; if (skipscan == true) goto skipquestslabel;

cout << "Height: (1.."<<scanner.maximageheight(dpi)-y<<"): "; fflush(stdout); cin >> h; if ((h > scanner.maximageheight(dpi)-y) or (h < 1)) skipscan = true; if (skipscan == true) goto skipquestslabel; skipquestslabel: if (not skipscan) { scanner.doscan(dpi,bpp, x,y,w,h); while (scanner.getdata() == 0) usleep(10000); string filename(apppath); filename.resize(filename.size()-2); filename+="/scannedimage.png";cout << "saving image to \"" << filename.data() << "\"\n"; pngwriter image(w, h, 1.0, filename.data()); int r = 0; int g = 0; int b = 0; if (bpp == 48) for (int j = 0 ; j < h; j++) for (int i = 0 ; i < w; i++) { scanner.getpixel(i, j, &r, &g, &b); image.plot(i, h-j-1, r, g, b); } else for (int j = 0 ; j < h; j++) for (int i = 0 ; i < w; i++) { scanner.getpixel(i, j, &r, &g, &b); image.plot(i, h-j-1, r << 8, g << 8, b << 8); } image.setcompressionlevel(1); image.close();//*/ scanner.cleardata(); cout << "wait...\n "; while ((scanner.getdata() != 5) and (scanner.getdata() != 16)) usleep(10000); } scanquest: cout << "want new scan? (y,s - scan, c - calibration): "; fflush(stdout); char scn; cin >> scn; if ((scn != 'y') and (scn != 's')) { if (scn == 'c') { scanner.calibration(); while (scanner.getdata() == 0) usleep(10000); scanner.cleardata(); goto scanquest; } else break; } } while (true); exitapp: scanner.close(); return 0; }

#66192
rip86oz написал:
Теперь встаёт вопрос как освободить память выделенную для хранения виртуальных адресов.

вы не тот вопрос ставите: а оно вообще надо? Зачем вам понадобилось освобождать память? Она сама освободится, если это будет нужно - система полагает, что память программе МОЖЕТ понадобится, и потому её не очищает. ИМХО - это правильное поведение.

#66194
AndreyMust19 написал:
А вот тип csl_imagedata - число, то разница есть.

в С++ ЕМНИП нет никакой разницы.

rip86oz написал:
Хотя в доках говорится, что по закрытии объекта вся память высвобождается.

а почему вы считаете, что она сразу должна нарисоваться в свободной?

#66219
drBatty написал:

а почему вы считаете, что она сразу должна нарисоваться в свободной?

Если создавать объект динамический, то память тоже не освобождается. Здесь привел не тот вариант.
Вообще по логике, память должна высвобождаться. Не вижу особых причин, чтобы этого не происходило. Разве что ядро резервирует этот объем, чтоб потом опять его не выделять.

#66232
rip86oz написал:
Вообще по логике, память должна высвобождаться. Не вижу особых причин, чтобы этого не происходило. Разве что ядро резервирует этот объем, чтоб потом опять его не выделять.

ну. так ИМХО и есть - резервирует. А зачем ей память освобождать в тот момент, когда она никому не нужна? У меня так постоянно 100% занято - не вижу трагедии, нужно будет - освободит.

#66247

А освободит-ли? smile Как-бы использование SWAP-а не стало предпочтительнее.Это ещё предстоит проверить.

#66264
rip86oz написал:
А освободит-ли? smile Как-бы использование SWAP-а не стало предпочтительнее.Это ещё предстоит проверить.

я замечал, что использование swap'а имеет намного более низкий приоритет (ИМХО так и должно быть), т.е. если в системе "занято" 100% памяти, но используется скажем 30%, то если выделить ещё 70%, то своп только появляется (система зачем-то старается оставить свободными примерно 1% памяти, т.е. выделяется не 100%, а 99%, и оставшийся кусочек берётся из свопа). Наверное это как-то настраивается, но мне и так нравится.

ЗЫЖ а вот венда зачем-то старается держать свободным чуть-ли не 50% :(

Войдите или зарегистрируйтесь, чтобы ответить.