GC и явное освобождение ресурсов
От: D.Triton Украина  
Дата: 01.09.06 07:51
Оценка:
Добрый день, господа!

Каким образом можно явно освободить память в .net 1.1.

Есть WinForms приложение с использованием DevExpress.

По закрытию окна, на котором расположен DataGrid данные не освобождаются даже
с помощью
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Что можете посоветовать? Что почитать и где посмотреть. Самые явные ошибки, которые я мог допустить?

К стати, по закрытию окна метод Dispose у формы вызывается.
Re: GC и явное освобождение ресурсов
От: Mab Россия http://shade.msu.ru/~mab
Дата: 01.09.06 08:04
Оценка: +2
Здравствуйте, D.Triton, Вы писали:

DT>Что можете посоветовать?

Взять Sci Tech Memory Profiler и посмотреть, что происходит в куче.
Re: GC и явное освобождение ресурсов
От: fmiracle  
Дата: 01.09.06 08:25
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>Каким образом можно явно освободить память в .net 1.1.

...
DT>Что можете посоветовать? Что почитать и где посмотреть. Самые явные ошибки, которые я мог допустить?

А что, все так плохо с памятью или это просто истерика из-за лишнего десятка мегобайт "черезмерно" отъедаемого программой из полугига доступных?

Дело в том, что, возможно, память была очищена, но не возвращена в систему. Это нормальная ситуация в .NET приложении — оно хапает много памяти про запас, потом спокойно ею пользуется. После вызова GC она может получить почти пустую кучу — для нее — но с точки зрения системы эта память занята — и в таск менеджере будет показываться, что прилада ее занимает. А сама прилада эту память в систему не отдает, поскольку считает, что она ей и самой еще пригодится для дальнейшей работы (затребовать память у операционки — занимает время). Особенно характерно это проявляется когда в системе много свободной памяти.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: GC и явное освобождение ресурсов
От: D.Triton Украина  
Дата: 01.09.06 08:38
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>Здравствуйте, D.Triton, Вы писали:


DT>>Каким образом можно явно освободить память в .net 1.1.

F>...
DT>>Что можете посоветовать? Что почитать и где посмотреть. Самые явные ошибки, которые я мог допустить?

F>А что, все так плохо с памятью или это просто истерика из-за лишнего десятка мегобайт "черезмерно" отъедаемого программой из полугига доступных?


F>Дело в том, что, возможно, память была очищена, но не возвращена в систему. Это нормальная ситуация в .NET приложении — оно хапает много памяти про запас, потом спокойно ею пользуется. После вызова GC она может получить почти пустую кучу — для нее — но с точки зрения системы эта память занята — и в таск менеджере будет показываться, что прилада ее занимает. А сама прилада эту память в систему не отдает, поскольку считает, что она ей и самой еще пригодится для дальнейшей работы (затребовать память у операционки — занимает время). Особенно характерно это проявляется когда в системе много свободной памяти.



Вообщем-то не 10, а 1.6 -2 гига.
Мы парсим огромный текстовый файл. вот после этих операций парсинга и происходит "утечка" памяти.

Комп свапиться начинает. Но вызов GC.Collect(), что я описа выше, ничего не дает
Re[3]: GC и явное освобождение ресурсов
От: VladGalkin Украина  
Дата: 01.09.06 09:00
Оценка:
Здравствуйте, D.Triton, Вы писали:


DT>>>Каким образом можно явно освободить память в .net 1.1.


Хм, вот под FW 1.1 сказать не могу, а случае 2.0 и large block of unmanaged memory можно было бы глянуть на MemoryPressure, в частности методы: GC.AddMemoryPressure и GC.RemoveMemoryPressure.
... << RSDN@Home 1.2.0 alpha rev. 651>>
ДЭ!
Re[3]: GC и явное освобождение ресурсов
От: pt4h Беларусь http://dzmitryhuba.blogspot.com/
Дата: 01.09.06 09:29
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>Здравствуйте, fmiracle, Вы писали:


F>>Здравствуйте, D.Triton, Вы писали:


DT>>>Каким образом можно явно освободить память в .net 1.1.

F>>...
DT>>>Что можете посоветовать? Что почитать и где посмотреть. Самые явные ошибки, которые я мог допустить?

F>>А что, все так плохо с памятью или это просто истерика из-за лишнего десятка мегобайт "черезмерно" отъедаемого программой из полугига доступных?


F>>Дело в том, что, возможно, память была очищена, но не возвращена в систему. Это нормальная ситуация в .NET приложении — оно хапает много памяти про запас, потом спокойно ею пользуется. После вызова GC она может получить почти пустую кучу — для нее — но с точки зрения системы эта память занята — и в таск менеджере будет показываться, что прилада ее занимает. А сама прилада эту память в систему не отдает, поскольку считает, что она ей и самой еще пригодится для дальнейшей работы (затребовать память у операционки — занимает время). Особенно характерно это проявляется когда в системе много свободной памяти.



DT>Вообщем-то не 10, а 1.6 -2 гига.

DT>Мы парсим огромный текстовый файл. вот после этих операций парсинга и происходит "утечка" памяти.

DT>Комп свапиться начинает. Но вызов GC.Collect(), что я описа выше, ничего не дает


Скажите, может быть в течение работы Вашего приложения создается много мелких долгоживущих объектов? Они постепенно перекочуют во 2-ое поколение и могут там очень долго жить... GC может не убирать 2-ое поколение, пока не заполнится первое. Учитывая это + адаптивность размера поколений (то есть размер поколения может изменяться) можем получить Ваш случай...
Похожую картину (по количеству использованной памяти) можно наблюдать при парсинге большого (N x 100MB) XML файла с построением DOM. Если есть возмжность, можно попробовать перейти на read only + forward only режим парсинга (как SAX для XML).

Еще одна возможная причина — какие-то объекты остались подписаны на события...

А целом, как сказал выше Mab воспользуйтесь профайлером.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: GC и явное освобождение ресурсов
От: D.Triton Украина  
Дата: 01.09.06 09:40
Оценка:
Здравствуйте, pt4h, Вы писали:

P>Скажите, может быть в течение работы Вашего приложения создается много мелких долгоживущих объектов? Они постепенно перекочуют во 2-ое поколение и могут там очень долго жить... GC может не убирать 2-ое поколение, пока не заполнится первое. Учитывая это + адаптивность размера поколений (то есть размер поколения может изменяться) можем получить Ваш случай...

P>Похожую картину (по количеству использованной памяти) можно наблюдать при парсинге большого (N x 100MB) XML файла с построением DOM. Если есть возмжность, можно попробовать перейти на read only + forward only режим парсинга (как SAX для XML).

P>Еще одна возможная причина — какие-то объекты остались подписаны на события...


P>А целом, как сказал выше Mab воспользуйтесь профайлером.


У меня появилась идея, но как-то она не очень нравится мне.


Что, если код парсинга перевести на чистый с++, там то я точно могу управлять памятью?
Стоит ли так поступать или нет? Вернее переходил ли кто-либо на с++ ради управления памяти (для отдельных алгоритмов).

По поводу 2-го поколения,
GC.Collect() аналогичен GC.Collect(2).
Так,что по 2-му поколению GC должен тоже "прогуляться".

Проблемма не только в парсинге. Когда я закачиваю данные в DevExpress Grid Control, то по закрытию формы данные не освобождаются также.
Ну во всяком случае за приемлимое время.

Ну с тем не так важно. А вот при парсинге проблемма. Просто на меня таск выставили, оптимизировать работу приложения с памятью. Мы эту прогу год почти пишем. Уже она (прога) стала солидненькой, жирком обросла. И ходить и оптимизировать все алгоритмя ломает.

Быстрым решением было бы переложить все на Garbage Collector, да вот он похоже ведет себя как сам захочет

Вот с профайлером поковыряться надо это факт. Правда сначала надо понять как им вообще пользоваться

Ну все равно спасибо за совет!
Re[5]: GC и явное освобождение ресурсов
От: fmiracle  
Дата: 01.09.06 10:02
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>У меня появилась идея, но как-то она не очень нравится мне.

DT>Что, если код парсинга перевести на чистый с++, там то я точно могу управлять памятью?
DT>Стоит ли так поступать или нет? Вернее переходил ли кто-либо на с++ ради управления памяти (для отдельных алгоритмов).

Я лично не делал, хотя не исключаю такой возможности.
Могу только сказать.ч то сам по себе парсинг огромных файлов не вызывает проблем в .NET и GC справляется.
Другое дело — как организован алгоритм. Видимо, там использовалось какое-то не очень удачное для именно больших файлов решение.
Пока не увидим — ничего сказать не сможем. Попробуй действительно поигратсья профайлерами...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: GC и явное освобождение ресурсов
От: IT Россия linq2db.com
Дата: 01.09.06 12:48
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>Вообщем-то не 10, а 1.6 -2 гига.

DT>Мы парсим огромный текстовый файл. вот после этих операций парсинга и происходит "утечка" памяти.

DT>Комп свапиться начинает. Но вызов GC.Collect(), что я описа выше, ничего не дает


Это симптомы того, что у вас в коде где-то происходит накопление данных. GC тут не при чём. Ищите места где вы складируете ваши данные и в дальнейшем их так и продолжаете держать. Послушайте что говорит Mab, возмите профайлер.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re: GC и явное освобождение ресурсов
От: nikov США http://www.linkedin.com/in/nikov
Дата: 01.09.06 13:18
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>По закрытию окна, на котором расположен DataGrid данные не освобождаются даже

DT>с помощью
DT>GC.Collect();
DT>GC.WaitForPendingFinalizers();
DT>GC.Collect();
DT>Что можете посоветовать? Что почитать и где посмотреть. Самые явные ошибки, которые я мог допустить?
DT>К стати, по закрытию окна метод Dispose у формы вызывается.

Скорее всего, Вы положили ссылку (прямую или косвенную) на Ваши данные в статическое поле какого-то класса. Если есть ссылка из статического поля, то никакой GC.Collect() не поможет. Dispose тоже скорее всего не трогает статические поля, потому что он — экземплярный метод.
Re[2]: GC и явное освобождение ресурсов
От: D.Triton Украина  
Дата: 01.09.06 14:47
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, D.Triton, Вы писали:


N>Скорее всего, Вы положили ссылку (прямую или косвенную) на Ваши данные в статическое поле какого-то класса. Если есть ссылка из статического поля, то никакой GC.Collect() не поможет. Dispose тоже скорее всего не трогает статические поля, потому что он — экземплярный метод.


Согласен, но что тогда делать с DevExpress формой (вернее ее потомком) и GridControl?
Я думаю, что данные там-то должны освобождаться нормально. Я же всего-навсего зафилил датасет и подсунул его Гриду.
Потом закрыл форму. У нее даже Dispose() вызвался Но память не освободилась.

У меня тут мысль пробежала. После удаления объектов из памяти GC производит ее дефрагментацию. Однако он не трогает "большие объекты".
Может быть в этом и есть дело. Может указатель NextObject не опускается в Хипе ниже этого большого объекта (формы со всем тем барахлом, что я в нее всунул)?
Re[3]: GC и явное освобождение ресурсов
От: ivasi  
Дата: 01.09.06 15:03
Оценка:
[DllImport("Psapi.dll")]
static extern bool EmptyWorkingSet(IntPtr hProcess);

public static void ClearSpace(System.IntPtr ptr)
{
EmptyWorkingSet(ptr);
GC.WaitForPendingFinalizers();
GC.Collect();
}

...
ClearSpace(EmptyWorkingSet(System.Diagnostics.Process.GetCurrentProcess().Handle);
...
Re[4]: GC и явное освобождение ресурсов
От: D.Triton Украина  
Дата: 01.09.06 15:15
Оценка:
Здравствуйте, ivasi, Вы писали:

I>[DllImport("Psapi.dll")]

I>static extern bool EmptyWorkingSet(IntPtr hProcess);

I>public static void ClearSpace(System.IntPtr ptr)

I>{
I> EmptyWorkingSet(ptr);
I> GC.WaitForPendingFinalizers();
I> GC.Collect();
I>}

I>...

I>ClearSpace(EmptyWorkingSet(System.Diagnostics.Process.GetCurrentProcess().Handle);
I>...


РАБОТАЕТ!!!! Только чего оно делает-то?

Спасибо огромное!!!!!
Re[5]: GC и явное освобождение ресурсов
От: ivasi  
Дата: 01.09.06 15:18
Оценка:
DT>РАБОТАЕТ!!!! Только чего оно делает-то? :)

DT>Спасибо огромное!!!!!


Собственно говоря мы ручками удаляем мусор...

EmptyWorkingSet
The EmptyWorkingSet function removes as many pages as possible from the working set of the specified process.

BOOL EmptyWorkingSet(
HANDLE hProcess // identifies the process
);

Parameters
hProcess
Handle to the process.
Return Value
If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks
You can also use the SetProcessWorkingSetSize function to do what EmptyWorkingSet does if you pass it 0xFFFFFFFF for the minimum and maximum sizes.

See Also
Process Status Helper Overview, PSAPI Functions, EnumProcesses, SetProcessWorkingSetSize
Re[6]: GC и явное освобождение ресурсов
От: ivasi  
Дата: 01.09.06 15:20
Оценка:
Следует обратить внимание что вызывается API функция Windows!
Re: GC и явное освобождение ресурсов
От: Аноним  
Дата: 01.09.06 13:44
Оценка:
А может все просто и имеется в виду тот факт, что в конструкторе DataSet вызывается GC.SuppressFinalize(this)? Эта тема уже многократно обсуждалась. См., например:
http://blogs.gotdotnet.ru/personal/mihailik/PermaLink.aspx?guid=1a6a6217-0d66-4009-8429-4c1ef8b27ae9
www.gotdotnet.ru/Forums/Data/132794.aspx


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[5]: GC и явное освобождение ресурсов
От: RustM Россия  
Дата: 01.09.06 17:17
Оценка:
Здравствуйте, D.Triton, Вы писали:

DT>Здравствуйте, ivasi, Вы писали:


Как говорится, м-да...
Об этом поведении писали здесь
Автор: fmiracle
Дата: 01.09.06


Дело в том, что, возможно, память была очищена, но не возвращена в систему. Это нормальная ситуация в .NET приложении — оно хапает много памяти про запас, потом спокойно ею пользуется. После вызова GC она может получить почти пустую кучу — для нее — но с точки зрения системы эта память занята — и в таск менеджере будет показываться, что прилада ее занимает. А сама прилада эту память в систему не отдает, поскольку считает, что она ей и самой еще пригодится для дальнейшей работы (затребовать память у операционки — занимает время). Особенно характерно это проявляется когда в системе много свободной памяти.


Только надо отметить что память системе будет возвращена, если ей она потребуется.

PS. Освобождение workinkset'a можно добится если свернуть прилржение.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Re[5]: GC и явное освобождение ресурсов
От: Denis Россия http://blogs.gotdotnet.ru/personal/Denis
Дата: 01.09.06 20:07
Оценка:
DT>Что, если код парсинга перевести на чистый с++, там то я точно могу управлять памятью?
DT>Стоит ли так поступать или нет? Вернее переходил ли кто-либо на с++ ради управления памяти (для отдельных алгоритмов).

изучал много различных Toolkits связанных с графикой, везде так и сделано.
EMC Software (www.emc.com)
PixTools/ISIS scanning
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.