Re[7]: Утечки памяти?
От: notacat  
Дата: 30.09.10 09:01
Оценка: -1
JR>Я конечно за то, чтобы закрывать такие ресурсы сразу, но и без этого утечки хёндлов в DotNet не будет. Признаться, наблюдаемое поведение совпадает с моими представлениями, но может быть мои представления ошибочны? Как мне увидеть то явление, о котором вы говорили — то есть наблюдаемую в диспетчере ктечку от незакрытых явно стримов?

Мы обсуждаем утечку от незакрытых стримов или утечку вообще? Не приведу я вам примера. Это ж сколько надо хэндлов держать, чтобы цифра в диспетчере заметно увеличилась? Конечно, это не показатель. Но вообще, программы обычно делают не одну единственную глупость, а много разных вещей. Лучше сразу научиться хэндлы закрывать, чем потом когда-нибудь искать источник неприятностей.

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

Ну давайте теперь про SafeHandle уточним. Когда будут хэндлы закрыты — при выходе из программы? Есть какая-то вероятность, что вот мы так все бросим, хэндлы сами собой через полчасика закроются, а программа будет продолжать работать?
Re[8]: Утечки памяти?
От: Jolly Roger  
Дата: 30.09.10 12:58
Оценка:
Здравствуйте, notacat, Вы писали:

N>Мы обсуждаем утечку от незакрытых стримов или утечку вообще?


Ну лично я готов обсуждать с Вами что угодно и сколько угодно Но вообще-то вроде Вы предлагали открывать в цикле стримы и это должно показать утечку памяти в диспетчере, что, в принципе, соответствует коду ТС. Но я не настаиваю, см. выше

N>Не приведу я вам примера.


Ну и ладно.

N>Это ж сколько надо хэндлов держать, чтобы цифра в диспетчере заметно увеличилась?


Да вобщем-то достаточно одного Диспетчер, он их поштучно считает.

N>Конечно, это не показатель.


А что тогда показатель?

N>Но вообще, программы обычно делают не одну единственную глупость, а много разных вещей. Лучше сразу научиться хэндлы закрывать, чем потом когда-нибудь искать источник неприятностей.


Совершенно с Вами согласен. Но на утечки памяти процесса это не влияет. Точнее, на ту память которую мы тут как-бы пытались обсуждать... но молчу, молчу, во внутренности системы не лезу

N>Про раздраженный тон — боюсь это ваши собственые эмоции при чтении так преломляются.


Вот и чудненько, так и зафиксируем для истории

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


Да я уже понял Бог с ним, с примером.

N>Ну давайте теперь про SafeHandle уточним.


Да-а-а-вайте Только чур, не обвинять меня опять, что я утаскиваю обсуждение в дебри ОС, я совсем чуть-чуть, а Вы сами первая начали

N>Когда будут хэндлы закрыты — при выходе из программы? Есть какая-то вероятность, что вот мы так все бросим, хэндлы сами собой через полчасика закроются, а программа будет продолжать работать?


Хёндлы файлов, как и многих других объектов, закрываются фунцией CloseHandle. Сам по себе хёндл это целое число, размером IntPtr. В DotNet этот хёндл заворачивается в потомка SafeHandle, который в своём методе Dispose и вызывает CloseHandle. Кроме того, у него есть унаследованный от CriticalFinalizerObject виртуальный деструктор, в котором он вызывает свой-же виртуальный Dispose. Ну а когда вызывается деструктор объекта, Вы наверняка знаете не хуже, а то и лучше меня. Так что при одной из сборок мусора хёндлы будут закрыты сборщиком, а связанные с объектами буферы, как и сами объекты будут собраны ещё раньше. Причем чем чаще будет происходить сборка, тем быстрее они будут закрыты. Но и это можно ускорить. Я например, добавил к примеру вызов двух функций

GC.Collect();
GC.WaitForPendingFinalizers();


после чего показания диспетчера вообще практически "замёрзли".

Так что вероятность тут практически 100% Но как Вы справедливо заметили, делать так не следует, прежде всего из-за недетерменированности момента закрытия хёндла, и всё это время объект, чей хёндл не закрыт, будет занят (не всегда, но — не углубляюсь ), а это может создать проблемы как для самого приложения, так и для сторонних процессов.

Ну и маленько для ТС. Пусть возьмёт эту функцию:

[DllImport("Kernel32.dll")]
static extern bool SetProcessWorkingSetSize(
    IntPtr hProcess,
    IntPtr dwMinimumWorkingSetSize,
    IntPtr dwMaximumWorkingSetSize);


вызывает её вот так

var d = new IntPtr(-1);
SetProcessWorkingSetSize(d, d, d);


И радуется маленькому размеру занимаемой "памяти". Только когда его будут бить, то пусть не обижается и не говорит, что его не предупреждали.
"Нормальные герои всегда идут в обход!"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.