Как высвободить память занимаемую функцией new при захвате > 85000 байт?
GC.Commit() не помогает....
Например: Мы открывает окно с контролами (мапять выделяется), закрываем его (только часть памяти освобождается)
открываем еще раз — еще кусок памяти система забирает. и так далее.
В конце рабочего дня прграмма занимает около 250Mb!!! При этом страшно тормазит!
Что делать???
12.01.05 16:00: Перенесено модератором из 'Проектирование' — Хитрик Денис
Здравствуйте, KBH, Вы писали:
KBH>Здравствуйте, master1, Вы писали:
M>>Как высвободить память занимаемую функцией new при захвате > 85000 байт? M>>GC.Commit() не помогает....
KBH>По-моему, нужно вызвать Dispose() компонента.
можно. я так и делаю....
Form fm = new fmMidi();
//fm.MdiParent = this;
fm.ShowDialog();
fm.Dispose();
fm = null;
Здравствуйте, master1, Вы писали:
KBH>>По-моему, нужно вызвать Dispose() компонента. M>можно. я так и делаю....
M> Form fm = new fmMidi(); M> //fm.MdiParent = this; M> fm.ShowDialog(); M> fm.Dispose(); M> fm = null;
M> GC.Collect(); M> GC.WaitForPendingFinalizers(); M> GC.Collect();
Dispose можно и не вызывать, если все ресурсы управляемые. Двойной вызов GC.Collect должен собрать весь мусор и освободить всю занятую память. Так что тут два варианта: либо у тебя где-то используются unmanaged resources, либо GC работает не правильно.
Здравствуйте, Mishka, Вы писали:
M>Здравствуйте, master1, Вы писали:
KBH>>>По-моему, нужно вызвать Dispose() компонента. M>>можно. я так и делаю....
M>> Form fm = new fmMidi(); M>> //fm.MdiParent = this; M>> fm.ShowDialog(); M>> fm.Dispose(); M>> fm = null;
M>> GC.Collect(); M>> GC.WaitForPendingFinalizers(); M>> GC.Collect();
M>Dispose можно и не вызывать, если все ресурсы управляемые. Двойной вызов GC.Collect должен собрать весь мусор и освободить всю занятую память. Так что тут два варианта: либо у тебя где-то используются unmanaged resources, либо GC работает не правильно.
Можно и не вызывать, всеравно толку нету
неуправляемых ресурсов я не использовал. А насчет GC... Ну как он может работать не правильно??
постоянно растет GC Handles, Gen 0 Collections,Gen 1 Collections,Gen 2 Collections
память высвобождается но не вся.
M>>Dispose можно и не вызывать, если все ресурсы управляемые. Двойной вызов GC.Collect должен собрать весь мусор и освободить всю занятую память. Так что тут два варианта: либо у тебя где-то используются unmanaged resources, либо GC работает не правильно.
M>Можно и не вызывать, всеравно толку нету M>неуправляемых ресурсов я не использовал. А насчет GC... Ну как он может работать не правильно??
M>постоянно растет GC Handles, Gen 0 Collections,Gen 1 Collections,Gen 2 Collections M>память высвобождается но не вся.
чуть не забыл! пастет назмер кучи объектов второго покаления! Gen 2 heap size
Здравствуйте, master1, Вы писали:
M>чуть не забыл! пастет назмер кучи объектов второго покаления! Gen 2 heap size
Ты что-то написал неверно. Хранишь мегабайты в статических хэштаблицах и так далее.
Здравствуйте, Poudy, Вы писали:
P>Здравствуйте, master1, Вы писали:
M>>чуть не забыл! пастет назмер кучи объектов второго покаления! Gen 2 heap size P>Ты что-то написал неверно. Хранишь мегабайты в статических хэштаблицах и так далее.
не. я создал новый проект. там всего 2 окна,
второе окно используется только для размещение контролов и там выделяется кусок памяти
byte[] b = new byte[100000];
for (int i=0;i<100000;i++)
{
b[i]=233;
}
и собственно все!
Здравствуйте, master1, Вы писали:
M>Как высвободить память занимаемую функцией new при захвате > 85000 байт?
Ну это будет "большой" объект с ним сборщик мусора работает отдельно. Память для них выделяется в отдельной куче и обект никогда не перемещается (т.е. куча не дефрагментируется). Сам объект сразу попадает во второе поколение, так что сборщик мусора может и не скоро до него добраться...
M>Что делать???
есть такой Performance Counter — Large Object Heap size, можешь посмотреть по нему освобождается ли память под большие объекты, если нет, то профайлером посмотреть кто его держит.
Здравствуйте, Mishka, Вы писали: M>Dispose можно и не вызывать, если все ресурсы управляемые. Двойной вызов GC.Collect должен собрать весь мусор и освободить всю занятую память. Так что тут два варианта: либо у тебя где-то используются unmanaged resources, либо GC работает не правильно.
Лучше вызывать Dispose явно, это более эффективно чем дожидаться вызова финалайзера... Вызов GC.Collect, даже двойной, очистку _всего_ мусора не гарантирует, насколько я знаю. До GEN2 дело скорее всего не дойдет если в GEN0 освободится достаточно памяти...
Здравствуйте, master1, Вы писали:
M>>>чуть не забыл! пастет назмер кучи объектов второго покаления! Gen 2 heap size P>>Ты что-то написал неверно. Хранишь мегабайты в статических хэштаблицах и так далее. M>не. я создал новый проект. там всего 2 окна, M>второе окно используется только для размещение контролов и там выделяется кусок памяти M> byte[] b = new byte[100000]; M> for (int i=0;i<100000;i++) M> { M> b[i]=233; M> } M>и собственно все!
Попробовал твой тест. Gen 2 heap size доростает до 250Кб потом сбрасывается до 50Кб, Large Object Heap Size стоит как вкопаный на 16384 байтах... Подозреваю что проблемы в неосвобожденных Unmanaged ресурсах...
Как рекомендуют лучшие собаководы из Microsoft:
1. Не вызывайте GC.Collect никогда
2. Если все же нужно, то оправдано это только после того как закончили работу с большими объектами
иначе можно получить decrease perfomance...
Здравствуйте, master1, Вы писали:
M>Как высвободить память занимаемую функцией new при захвате > 85000 байт? M>GC.Commit() не помогает....
Никак объекты такого размера (если не изменяет память большие 20 Кил) помещаются в специальный хип. Этот хип создан по принципу malloc-а, т.е. на базе связанного списка свободных и занятых блоков. Память в нем не помпактися.
M>Например: Мы открывает окно с контролами (мапять выделяется), закрываем его (только часть памяти освобождается) M>открываем еще раз — еще кусок памяти система забирает. и так далее. M>В конце рабочего дня прграмма занимает около 250Mb!!! При этом страшно тормазит!
M>Что делать???
Ничего не делать. Если вы не теряете памяь, то эти блоки будут в последствии повторно использованя.
Если охота избежать вообще подобных заемов, то просто не занимайте таких окромных объемов за раз. Режте память на блоки. Ну, или создайте пул таких буферов и уравляйте им явно.
... << RSDN@Home 1.1.4 beta 3 rev. 273>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Spaider, Вы писали:
S>Здравствуйте, Mishka, Вы писали:
M>>Dispose можно и не вызывать, если все ресурсы управляемые.
S>Ша, медуза S>А хэндлы окон у нас уже стали управляемыми? А если на форме Control'ов до пупа?
А что, если я Dispose у контрола не вызову, так handle у меня навечно в памяти останется висеть?
Здравствуйте, Mishka, Вы писали:
M>Здравствуйте, Spaider, Вы писали:
S>>Здравствуйте, Mishka, Вы писали:
M>>>Dispose можно и не вызывать, если все ресурсы управляемые.
S>>Ша, медуза S>>А хэндлы окон у нас уже стали управляемыми? А если на форме Control'ов до пупа?
M>А что, если я Dispose у контрола не вызову, так handle у меня навечно в памяти останется висеть?
Вот чего было найдено на простораз тырнета, конкретно здесь:
When a control is disposed, it disposes all of its children. The only time you get automagic disposal of controls is when you do Application.Run(new Form()). (We like to call this showing the form modelessly). When the form gets WM_CLOSE message, it starts cleaning itself up while it can.
However if you do a Form.ShowDialog(), the form is NOT disposed. (We like to call this showing the form modally). This is because you may want to go in after the form has closed and look at the state of the child controls to determine the next action of your program.
If you add and remove controls from your form dynamically, you should call dispose on them – otherwise you’ll accumulate extra unwanted window handles in your process. Remember you only have to dispose the topmost control – so if you’re swapping in and out a panel – disposing the panel disposes it’s child controls.
S>Вот чего было найдено на простораз тырнета, конкретно здесь:
S>
S>When a control is disposed, it disposes all of its children. The only time you get automagic disposal of controls is when you do Application.Run(new Form()). (We like to call this showing the form modelessly). When the form gets WM_CLOSE message, it starts cleaning itself up while it can.
S>However if you do a Form.ShowDialog(), the form is NOT disposed. (We like to call this showing the form modally). This is because you may want to go in after the form has closed and look at the state of the child controls to determine the next action of your program.
S>If you add and remove controls from your form dynamically, you should call dispose on them – otherwise you’ll accumulate extra unwanted window handles in your process. Remember you only have to dispose the topmost control – so if you’re swapping in and out a panel – disposing the panel disposes it’s child controls.
Нда... вот вам и автоматическая сборка мусора от мелкософта, а то я то думал обрадоваться
--
То, что вы уникальны еще не значит, что от вас есть толк