Memory Management при C#

20 отговора 0 прегледа
#1

Memory Management при C#

Проектът е десктоп приложение за джамците. Има проблем с паметта:

Същия проблем имах, когато се занимавах с андроид/джава миналата година, на устройство с ограничени ресурси. Но ето, че се случва и на десктоп с 4 гиги памет.
Като цяло впечатлението ми е, че това се случва, когато се борави с много големи обеми от данни, които се сменят твърде бързо, за да може GC да реагира. Същото приложение (както и андроидското тогава), работи без проблем, ако юзера работи по-флегматично.
Огромният проблем на тези езици е липсата на каквато и да е възможност за ръчно освобождаване на памет. Съответно, тогава правих доста еквилибристики за да стабилизирам положението, но сега нищо не ми хрумва. Още повече, че проектът е доста тлъст и няма как да се внасят тепърва кардинални проблеми.

Всякакви съвети ще са добре дошли и евентуално поляти с бира.

Отговор
в отговор на Pekoнcтpykтop #2

Re: Memory Management при C#

Тук по-скоро рисуваш или твърде голяма картина или някоя от стойностите ти е неточна. Примерно:

g.DrawRect(0, 0, 300, NaN);

Някъде по кода ти е грешката.

На VS-то - Debug - Exceptions - и дай чек на Тhrown на CLRExceptions. Пусни и виж на кой ред гърми.


_________________
Ben Shalom Bernanke
Отговор
в отговор на Pekoнcтpykтop #3

Re: Memory Management при C#

Яли сме го тоя.

Навсякъде където създаваш нейтив ресурси - фонтове, бръшове, дц-та и прочие ги диспозвай веднага. Освен тва, мисля, грешката не е точно ООМ ма се 'транслира' до нея.

Pain looks great on other people. That’s what they’re for.
Отговор
в отговор на Pekoнcтpykтop #4

Re: Memory Management при C#

Имай впредвид, че когато алокейтваш в хийпа обект по-голям от 80К, то той директно отива в лардж обджект хийпа, който не се фрагментира.По този начин ако непрекъснато алокейтваш обекти с различна големина по-голяма от 80К неминуемо ще достигнеш до OutOfMemoryException.

Това е и най-честата грешка допускана от програмисти за OutOfMemoryException.

Шибни Гуугъл и чети за LOH (large object heap) c sharp.

Редактирано от Aaron на

Отговор
в отговор на Wipelicious #5

Re: Memory Management при C#

Имаше и още няква тъпотия, която водеше до тва, ма то беше много специфично, кат се рънваше апп-а не с истински адаптер ми с VDI, така че едва ли е твоя кейс.

Pain looks great on other people. That’s what they’re for.
Отговор
в отговор на Wipelicious #6

Re: Memory Management при C#

Да. И на тоя Image веднага след като го изрисува, трябва да му викне Dispose също.


_________________
Ben Shalom Bernanke
Отговор
в отговор на Pekoнcтpykтop #7

Re: Memory Management при C#

Ето това е много добра статия за LOH-a...

The Dangers of the Large Object Heap

Отговор
в отговор на Pekoнcтpykтop #8

Re: Memory Management при C#

Със сигурност проблемът ти не е от картинката, щом имаш 4 гигабайта рам. GD, което гълта памет като хала, заема двойно размера на битмап, т.е. ширина в пиксели * височина в пиксели * 32 бита / 8 бита/байт * 2. Microsoft Drawing със сигурност взема по-малко, но дори и да взема пак толкова, гърмеж трябва да се получи само при картинки > 20к х 20к пиксела.

По-вероятно ми се струва това, което Арун е написал. От личния ми опит си спомням, че VS ми е връщало Out of Memory или при грешка в кода или от обекти по 65к, които са неподходящо декларирани.

Отговор
в отговор на croesus #9

Re: Memory Management при C#

Аве мога да се басирам, че проблема му е от следните две (фатални в неговия случай неща):

1. хендълите не са безкрайни
2. разчитане на ГЦ-то да финализира

И ако му погледнеш стек трейса, ще видиш, че ексепшъна се транслира от вин32 код, което не е точно менидж ООМ

Pain looks great on other people. That’s what they’re for.
Отговор
в отговор на Wipelicious #10

Re: Memory Management при C#

очевидно е, че хендълите са капсулирани от сишарпски обекти и не се освобождават преди да се е освободил обекта.

Отговор
в отговор на Aaron #11

Re: Memory Management при C#

Да, това изглежда като най-логичното обяснение, благодаря за което. Както и за статията по-долу.

Отговор
в отговор на Pekoнcтpykтop #12

Re: Memory Management при C#

A System.GC.Collect() върши ли каквото се очаква, или е само за парлама?

Отговор
в отговор на Pekoнcтpykтop #13

Re: Memory Management при C#

Нека да го повторя още веднъж, щото имам чувството, че говорим на различни езици и C# не ти е от силните страни (ти беше C dev май). Това не е managed OOM (и не е ООМ изобщо) - няма да ти помогне GC.Collect() (но да, работи).

Pain looks great on other people. That’s what they’re for.
Отговор
в отговор на Pekoнcтpykтop #14

Re: Memory Management при C#

точно затова обектите, които държат хелндели поддържат Dispose.

Отговор
в отговор на Pekoнcтpykтop #15

Re: Memory Management при C#

Точно в очевидното е проблемът. Нейтив ресурс ти разчита на гарбидж колект на врапера. Хийповете са различни и се менажират по различен начин.

I have sold less books on sex than Stephen Hawking has on physics -- Madonna
Отговор
в отговор на Pekoнcтpykтop #16

Re: Memory Management при C#

Между другото - неща които е добре да се имат предвид когато от managed среда викаме C:

В типичната C програма обектите с по-дълъг живот са в хийпа, PAINTSTRUCT обикновено живее в C стека.

Хендъли-мендъли може би са оптимизирани с некъв вид пуулове, кеширане, етц... да не фрагментират нейтив хийпа по-зле от прокъсан парцал, но PAINTSTRUCT едва ли некой е кодил оптимизация при положение, че на всеки WM_PAINT я заделяме с malloc :)

Тоест това, което изглежда като невинна локална променлива, реално избушва нейтив хийпа по най-възможно кофтия начин.

Като минимум консидерни 'локалните' C променливи да ги направиш мембъри, въпреки че по тоя начин отваряш кутията с ебати кофти червеите :)

Програмирането е ебати кефа, особено ако си общо взето напълно изтрещял

I have sold less books on sex than Stephen Hawking has on physics -- Madonna
Отговор
в отговор на Eвлaмпи Пoпдимитpoв #17

Re: Memory Management при C#

Нищо не е нейтив, всичко си е 100% .нет
По принцип, изобщо не се занимавам с глупости като c#/java, но искат проекта за вчера, пък и не са особено претенциозни.

Отговор
в отговор на Pekoнcтpykтop #18

Re: Memory Management при C#

"...но искат проекта за вчера, пък и не са особено претенциозни"

Обичайните жидомасони тип балък, дето на бае ти Ганя са му на къс пас реално предполагам :)

I have sold less books on sex than Stephen Hawking has on physics -- Madonna
Отговор
в отговор на Pekoнcтpykтop #19

Re: Memory Management при C#

Те по-нагоре са ти дали няколко добри идеи. Ама как го рисуваш тоя Image - да не ти е background на формата? И на всяко нейно прерисуване да алокираш наново памет да image-а без да му викаш Dispose.



Eeeeeeeeeeeeeeeaaaaaaasy rider
Отговор
в отговор на Lupi #20

Re: Memory Management при C#

Не, ресурсите се алокират на единствено място и живеят докато са нужни. Поне над .net слоя, тоест там, където пиша аз. Вече в самия фреймуорк как са реализирани нещата, нямам идея. Все пак, малко преди да изгърми, цялата форма става черна, което по принцип се случва, когато на джамците им свършат GDI хендълите. Което пък прави теорията, че освобождаването на тия хендъли е обвързано с унищожаването на самите обекти, които ги капсулират, (което пък не се случва) най-приемлива от всичко. И всъщност гърми не защото свършва паметта, ами защото свършват GDI хендълите.
Въпроса е какво да се прави и кой да се псува.

Отговор