|
Тема
|
Out of memory
|
|
Автор |
AйeзCeдaй ((бойна)) |
Публикувано | 29.10.12 15:11 |
|
и някаква идея как да го разреша....
щото
| |
|
Първо трябва да разбереш защо го получаваш, а после ще му мислим как да го разрешиш.
Това може да се получи основно по две причини. Първата е очевидна - опитваш се да резервираш повече памет, отколкото има. 32 битови приложения писани на Делфи могат да адресират максимум 2 GB памет. Ако си го достигнала този лимит, единственото което можеш да направиш... Сещаш се, няма какво да ти обяснявам
Втората причина е фрагментация на адресното пространство. Свободна памет има повече, отколкото се опитваш да резервираш, но няма достатъчно голям блок. Давам пример, за да стане по-ясно. Представи си, че имаш 10 еднакви кутии, наредени в редичка една до друга. Имаш летви с дължина по 2 или 3 кутии. Слагаш в началото една летва, която заема първите 3 кутии. След нея ена 2-ка, после 3-ка и после пак 2-ка. Така всички кутии са ти заети. После освобождаваш кутиите, заето от двете 2-ки. В този момент имаш 4 свободни кутии. Но ако се опиташ да сложиш една летва 3-ка, то няма да има къде, защото имаш 2 свободни блока от по 2 кутии. Надявам се с това малко "дървено" обяснение да съм хвърлил светлина върху ситуацията
Това фрагментиране на адресното пространство е проблем, с който в Делфи е малко трудно да се пребориш. Обърни внимание, че става въпрос за фрагментиране на адресното пространство, а не на паметта. В една среда като .NET например, garbage collector-а е в състояние да премести втората летва, така че да направи място за третата 3-ка, но в делфи няма начин memory manager-а да ти дефрагментира паметта, защото не знае къде си пазиш референции към създадените обекти.
За да се бориш с фрагментирането на адресното пространство трябва да си резервираш паметта разумно. Две често настъпвани мотики са streams и data sets. Представи си, че имаш memory stream, в който почваш да пишеш. Той си е заделил някакво количество памет. Когато то се напълни, се резервира нов, по-голям блок, и текущото съдържание се копира в новия блок, като стария се освобождава (разбира се, възможно е да има ситуация, в която да се дорезервира паметта непосредствено след текущия буфер, но това на практика никога не се случва). Продължаваш да пишеш в стрийма, а блоковете памет си хвърчат. Разумното управление на паметта в случая е, преди да почнеш да пишеш в стрийма, да му сетнеш размера до който ще стигне, за да си резервира паметта наведнъж. Естествено, това е в случай че знаеш колко голям ще е. В противен случай можеш да намалиш частично ефекта, като резервираш големи блокове. Когато тръгне да се препълва, увеличаваш размера пак ти.
Нещо подобно става с някои data set-а (със сигурност така е при Interbase Express). Записите в резултат на заявката не се фетчват наведнъж, а при необходимост. IBX има пропърти Unidirectional, чрез което можеш да го накараш да не пази всичките записи, но в този случай можеш да обхождаш записите само напред и не можеш да се връщаш назад. Не е подходящо, ако го показваш в грид.
Всичко това са само догадки, защото не си дала много информация за твоя случай. Кажи дали съм уцелил причината или дай малко повече информация какво точно се случва при теб
Linux isn't free, it's worthless.
| |
|
90% съм сигурен, че е свързано именно с фрагментиране на паметта, което в някои случаи може да достигне невероятни размери - половината памет свободна, а няма къде да заделиш достатъчно голям свободен блок :)
Mixy
| |
Тема
|
Re: Out of memory
[re: Mixy]
|
|
Автор |
Naki (Company PC Guy) |
Публикувано | 30.10.12 12:16 |
|
Хмм, чудя се - не е ли някакси подобрено това в RAD Studio XE/XE2/XE3?
| |
|
От Делфи 2006 (мисля) нагоре смениха мемори мениджъра. При него има три области, от които се резервират съответно малки (<2.5KB), средни (2.5KB-260KB) и големи (>260KB) блокове памет, както и редица други подобрения. Като цяло се държи много по-добре от този в 5-цата. С проста прекомпилация от 5 на 2006, в някои сценарии сме постигали 10 пъти увеличение на производителността.
Linux isn't free, it's worthless.
| |
|
ами, локалозирах проблема и силно се надам се, че го разреших...
(памет си имам ... ... достатъчно)
първо - да, имах проблем с няколко data sets (oracle), които бяха доста обемни. Разреших го проблема с оптимизация и т.н.
Второто беше, че имах един огромен bmp file.
Третото, че при build използвах packages, от които нямах нужда.
За момента всичко е наред... (и се надявам все така да е )
| |
|
|
|
|