WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 14.06.20 15:04
Оценка:
В продолжении темы http://rsdn.org/forum/dotnet/7753095.1
Автор: igor-booch
Дата: 13.06.20

Создал минимальное воспроизводящее приложение.

Условия воспроизведения:
1) Visual Studio 2017
2) Приложение WPF
3) Запуск приложение под отладчиком
4) код окна WPF

using System.Windows;

namespace ReproduceFinalizerMemoryLeak
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            do
            {
                Item item = new Item();
            } while (true);

            InitializeComponent();
        }
    }

    public class Item
    {
        private byte[] _bytes;

        public Item()
        {
            _bytes = new byte[10000];
        }

        ~Item()
        {

        }
    }
}


Что присходит:
Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.

В моем реальном WPF приложении утечка памяти просходит без отладки и в более мягких условиях, но проявления те же: финализаторы не вызываются, происходит учечка памяти.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 16:21
Оценка:
во-первых, при отладке код работает по-другому, если ты добавишь в деконструктор вот такой код:
 ~Item()
        {
            using (System.IO.StreamWriter file =    new System.IO.StreamWriter(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"WriteLines.txt"), true))
            {
                file.WriteLine("Item's finalizer is called.");
            }
            Console.WriteLine("Item's finalizer is called.");
        }


скомпилируешь под релиз и запустишь, то ты увидишь, что ничего не отваливается, а деконструктор вызывается

во-вторых, проблема у тебя совсем другая, в wpf источники утечки, как правило , совсем другие, так что данный пример- не в тему

сорри, надо и
do
            {
                Item item = new Item();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            } while (true);


вызывать
Отредактировано 14.06.2020 16:57 takTak . Предыдущая версия .
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 18:30
Оценка:
хм.. занятный пример: если вместо

 _bytes = new byte[10000]


сделать

 _bytes = new byte[100000]


то тогда всё работает

либо надо вызывать

do
            {
                Item item = new Item();
                GC.Collect();
                GC.WaitForPendingFinalizers();
               
            } while (true);
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: Osaka  
Дата: 14.06.20 20:07
Оценка:
T>сорри, надо и
T>
T>do
T>            {
T>                Item item = new Item();
T>                GC.Collect();
T>                GC.WaitForPendingFinalizers();
T>            } while (true);
T>


T>вызывать

Вроде достаточно sleep(0) внутри цикла вызывать.
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 20:18
Оценка:
T>>сорри, надо и
T>>
T>>do
T>>            {
T>>                Item item = new Item();
T>>                GC.Collect();
T>>                GC.WaitForPendingFinalizers();
T>>            } while (true);
T>>


T>>вызывать

O>Вроде достаточно sleep(0) внутри цикла вызывать.

не-а, сам по себе Thread.Sleep(1), конечно, context switch производит, но от memory leak это не избавляет
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 20:46
Оценка:
IB>Что присходит:
IB>Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.

IB>В моем реальном WPF приложении утечка памяти просходит без отладки и в более мягких условиях, но проявления те же: финализаторы не вызываются, происходит учечка памяти.


забавно: если деконструктор

~Item()
{
}


полностью убрать, то всё работает
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: VladCore  
Дата: 14.06.20 20:57
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>В продолжении темы http://rsdn.org/forum/dotnet/7753095.1
Автор: igor-booch
Дата: 13.06.20

IB>Создал минимальное воспроизводящее приложение.



а так?

IB>
IB>using System.Windows;

IB>namespace ReproduceFinalizerMemoryLeak
IB>{
IB>    /// <summary>
IB>    /// Interaction logic for MainWindow.xaml
IB>    /// </summary>
IB>    public partial class MainWindow : Window
IB>    {
IB>        public MainWindow()
IB>        {
IB>            do
IB>            {
IB>                TheMethod();
IB>            } while (true);

IB>            InitializeComponent();
IB>        }
        
        TheMethod() { Item item = new Item(); }
IB>    }

IB>    public class Item
IB>    {
IB>        private byte[] _bytes;

IB>        public Item()
IB>        {
IB>            _bytes = new byte[10000];
IB>        }

IB>        ~Item()
IB>        {

IB>        }
IB>    }
IB>}
IB>


IB>Что присходит:

IB>Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.

IB>В моем реальном WPF приложении утечка памяти просходит без отладки и в более мягких условиях, но проявления те же: финализаторы не вызываются, происходит учечка памяти.
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 14.06.20 21:05
Оценка:
Здравствуйте, takTak, Вы писали:

T>забавно: если деконструктор

T>полностью убрать, то всё работает

Чего ж тут забавного? Объекты перестает держать fqueue и GC прекрасно справляется со сборкой.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 21:12
Оценка:
T>>забавно: если деконструктор
T>>полностью убрать, то всё работает

НС>Чего ж тут забавного? Объекты перестает держать fqueue и GC прекрасно справляется со сборкой.


вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,
и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,
если же взять _bytes = new byte[10000], то происходит outOfMemory
Re[4]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 14.06.20 21:21
Оценка: +1
Здравствуйте, takTak, Вы писали:

T>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,


Он не может там подчистить без вызова финализаторов, а это потенциально долго.

T>и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,


100К попадает в LOH, там несколько другие алгоритмы.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 21:25
Оценка:
VC>

VC>а так?


IB>>
IB>>using System.Windows;

IB>>namespace ReproduceFinalizerMemoryLeak
IB>>{
IB>>    /// <summary>
IB>>    /// Interaction logic for MainWindow.xaml
IB>>    /// </summary>
IB>>    public partial class MainWindow : Window
IB>>    {
IB>>        public MainWindow()
IB>>        {
IB>>            do
IB>>            {
IB>>                TheMethod();
IB>>            } while (true);

IB>>            InitializeComponent();
IB>>        }
...

IB>>        ~Item()
IB>>        {

IB>>        }
IB>>    }
IB>>}
IB>>





не-а, это ничего не меняет... и с чего оно должно было бы измениться, здесь же не lambda-выражение\closure, а обычная локальная переменная


единственное, что всё меняет: это наличие или отсутствие деконструктора
Re[5]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 21:29
Оценка:
T>>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,

НС>Он не может там подчистить без вызова финализаторов, а это потенциально долго.


если бы в Item не было вы массива, то всё бы тоже работало, даже с наследованием,
проблема в сочетании деконструктора и небольшого массива внутри объекта

T>>и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,


НС>100К попадает в LOH, там несколько другие алгоритмы.


да, согласен, там другой алгоритм, и он справляется
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 14.06.20 21:43
Оценка:
T>>>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,

НС>>Он не может там подчистить без вызова финализаторов, а это потенциально долго.


T>если бы в Item не было вы массива, то всё бы тоже работало, даже с наследованием,

T>проблема в сочетании деконструктора и небольшого массива внутри объекта



не, даже без вложенного массива комбинация деконструктора и бесконечного цикла ведёт к outofmemory,
хотя в finalizer программа регулярно заходит
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.06.20 03:46
Оценка: +1
Здравствуйте, takTak, Вы писали:
T>единственное, что всё меняет: это наличие или отсутствие деконструктора
Деконструктор в дотнет — это метод Deconstruct. Он применяется для паттерн-матчинга и для деконструирующих присваиваний.
А то, о чём вы говорите, называется финализатором.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 06:30
Оценка:
T>>единственное, что всё меняет: это наличие или отсутствие деконструктора
S>Деконструктор в дотнет — это метод Deconstruct. Он применяется для паттерн-матчинга и для деконструирующих присваиваний.
S>А то, о чём вы говорите, называется финализатором.

забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор",
"финализатор" на https://ru.wiktionary.org/ не находится
Re[5]: WPF. Финализаторы не вызываются. Утечка памяти
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.06.20 07:00
Оценка: +1
Здравствуйте, takTak, Вы писали:
T>забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор",
T>"финализатор" на https://ru.wiktionary.org/ не находится
Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 07:15
Оценка:
T>>забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор",
T>>"финализатор" на https://ru.wiktionary.org/ не находится
S>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.


другие люди почему-то используют...
https://www.geeksforgeeks.org/destructors-in-c-sharp/

https://www.edureka.co/blog/destructor-in-java/

если обратно к нашим баранам, то
Use of finalize() methods should be avoided. They are not a reliable mechanism for resource clean up and it is possible to cause problems in the garbage collector by abusing them.
что мы, в принципе, на этом примере и видим
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 15.06.20 08:50
Оценка: +1
Здравствуйте, takTak, Вы писали:

T>проблема в сочетании деконструктора и небольшого массива внутри объекта


Нет. Проблема в большом количестве финализаторов и быстром выжирании пулов поколений.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 09:17
Оценка:
T>>проблема в сочетании деконструктора и небольшого массива внутри объекта

НС>Нет. Проблема в большом количестве финализаторов и быстром выжирании пулов поколений.


ну да, похоже на такое...

как вообще происходит "быстрое выжирание пулов поколений" и почему gc.collect этому "выжиранию" препятствует?
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 15.06.20 09:41
Оценка:
Здравствуйте, takTak, Вы писали:

T>как вообще происходит "быстрое выжирание пулов поколений"


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

T>и почему gc.collect этому "выжиранию" препятствует?


Потому что останавливает выделение и дает отработать финалайзерам.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[9]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 09:56
Оценка:
T>>как вообще происходит "быстрое выжирание пулов поколений"

НС>Путем быстрого выделения большого количества объектов.


T>>и почему gc.collect этому "выжиранию" препятствует?


НС>Потому что останавливает выделение и дает отработать финалайзерам.



для меня лично такое- это откровенный баг: если автоматическое управление памятью с выделением памяти под большие обьекты справляется, а с выделением паняти под маленькие объекты не справляется, то это — полная ерунда ...
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.06.20 10:00
Оценка:
Здравствуйте, takTak, Вы писали:

T>>>проблема в сочетании деконструктора и небольшого массива внутри объекта


НС>>Нет. Проблема в большом количестве финализаторов и быстром выжирании пулов поколений.


T>ну да, похоже на такое...


T>как вообще происходит "быстрое выжирание пулов поколений" и почему gc.collect этому "выжиранию" препятствует?

gc.collect как раз и переводит из поколения в поколение. Со старшими поколениями видно и происходит проблема с финализаторами.
Там считается если уж попал во 2 е поколение то это на долго.
А GC.WaitForPendingFinalizers(); принудительно дожидается пока все финализаторы не сработают
и солнце б утром не вставало, когда бы не было меня
Re[10]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 15.06.20 10:26
Оценка:
Здравствуйте, takTak, Вы писали:

T>для меня лично такое- это откровенный баг


Для тебя лично. Этому поведению уже 20 лет скоро.

T>: если автоматическое управление памятью с выделением памяти под большие обьекты справляется, а с выделением паняти под маленькие объекты не справляется, то это — полная ерунда ...


Полная ерунда это писать финалайзеры не соображая как это работает. Сама идея делать финалайзеры без неуправляемых ресурсов уже бред.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[11]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 11:06
Оценка:
T>>для меня лично такое- это откровенный баг

НС>Для тебя лично. Этому поведению уже 20 лет скоро.


T>>: если автоматическое управление памятью с выделением памяти под большие обьекты справляется, а с выделением паняти под маленькие объекты не справляется, то это — полная ерунда ...


НС>Полная ерунда это писать финалайзеры не соображая как это работает. Сама идея делать финалайзеры без неуправляемых ресурсов уже бред.



так я лично поэтому всегда Dispose и пользовался, краем уха слышал, что пользоваться finalizer не стоит...

так нафига finalizer воообще, если это банально не работает ?
Re[12]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 15.06.20 11:15
Оценка:
Здравствуйте, takTak, Вы писали:

T>так нафига finalizer воообще, если это банально не работает ?


Для неуправляемых ресурсов и умеющих ими правильно пользоваться.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[12]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.06.20 12:24
Оценка:
Здравствуйте, takTak, Вы писали:

НС>>Полная ерунда это писать финалайзеры не соображая как это работает. Сама идея делать финалайзеры без неуправляемых ресурсов уже бред.



T>так я лично поэтому всегда Dispose и пользовался, краем уха слышал, что пользоваться finalizer не стоит...


T>так нафига finalizer воообще, если это банально не работает ?


https://habr.com/ru/post/89720/
и солнце б утром не вставало, когда бы не было меня
Re[7]: WPF. Финализаторы не вызываются. Утечка памяти
От: bnk СССР http://unmanagedvisio.com/
Дата: 15.06.20 12:37
Оценка: +2
Здравствуйте, takTak, Вы писали:

S>>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.


T>другие люди почему-то используют...


И они не правы, потому что слово "finalizer" для того и придумали, чтобы избежать слова "destructor".
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: Слава  
Дата: 15.06.20 12:44
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>В продолжении темы http://rsdn.org/forum/dotnet/7753095.1
Автор: igor-booch
Дата: 13.06.20

IB>Создал минимальное воспроизводящее приложение.

Мне кажется, что в оригинальном вопросе у вас в финализаторе освобождалось что-то другое. Зачем вам финализатор, если у вас нет неуправляемых ресурсов?
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 12:56
Оценка:
S>>>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.

T>>другие люди почему-то используют...


bnk>И они не правы, потому что слово "finalizer" для того и придумали, чтобы избежать слова "destructor".



имхо никакого смысла плодить ненужные сущности нет: могли назвать недерминистическим дестрактором, тогда всем было бы всё понятно,
а чего стоит их "selectMany" в linq !? Поубибав бы(c)
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти
От: _NN_ www.nemerleweb.com
Дата: 15.06.20 13:15
Оценка: +1
Здравствуйте, bnk, Вы писали:

bnk>И они не правы, потому что слово "finalizer" для того и придумали, чтобы избежать слова "destructor".


Ага, слово то дали другое, а синтаксис в C# скопирован с деструкторов.
Лучше бы как в Java пиши полностью: public override void Finalize(), тогда бы и меньше людей пихало бы в код финализаторов.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: WPF. Финализаторы не вызываются. Утечка памяти
От: bnk СССР http://unmanagedvisio.com/
Дата: 15.06.20 13:21
Оценка:
Здравствуйте, _NN_, Вы писали:

bnk>>И они не правы, потому что слово "finalizer" для того и придумали, чтобы избежать слова "destructor".


_NN>Ага, слово то дали другое, а синтаксис в C# скопирован с деструкторов.

_NN>Лучше бы как в Java пиши полностью: public override void Finalize(), тогда бы и меньше людей пихало бы в код финализаторов.

Компромисс? Людям нужны знакомые вещи, пусть они немного и не такие какими кажутся

https://youtu.be/wIHfaH9Kffs
Re[10]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 15.06.20 13:25
Оценка: :)))
bnk>>>И они не правы, потому что слово "finalizer" для того и придумали, чтобы избежать слова "destructor".

_NN>>Ага, слово то дали другое, а синтаксис в C# скопирован с деструкторов.

_NN>>Лучше бы как в Java пиши полностью: public override void Finalize(), тогда бы и меньше людей пихало бы в код финализаторов.

bnk>Компромисс? Людям нужны знакомые вещи, пусть они немного и не такие какими кажутся


ага, если что-то выглядит как утка, но то мяукуает, то хрюкает, то как это назвать ?
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 15.06.20 13:51
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, igor-booch, Вы писали:


IB>>В продолжении темы http://rsdn.org/forum/dotnet/7753095.1
Автор: igor-booch
Дата: 13.06.20

IB>>Создал минимальное воспроизводящее приложение.

С>Мне кажется, что в оригинальном вопросе у вас в финализаторе освобождалось что-то другое. Зачем вам финализатор, если у вас нет неуправляемых ресурсов?

Это модельное (не реальное приложение). Я его создал, что хоть как-то продемонстрировать проблему. В реальной приложении финализатор не пустой и нет бесконечных циклов в конструкторе, но утечка памяти такая же.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
От: pilgrim_ Россия  
Дата: 15.06.20 15:24
Оценка: 74 (1)
Здравствуйте, Sinclair, Вы писали:

S>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.


Тем не менее в спецификации C# деструкторы есть : https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#destructors
Re[7]: WPF. Финализаторы не вызываются. Утечка памяти
От: _NN_ www.nemerleweb.com
Дата: 16.06.20 04:59
Оценка:
Здравствуйте, pilgrim_, Вы писали:

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


S>>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.


_>Тем не менее в спецификации C# деструкторы есть : https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#destructors


Ага. Повбивав би
Дать название из C++, а поведение совсем не такое как у деструкторов из C++:

Execution of the destructor for the instance may occur at any time after the instance becomes eligible for destruction.
When an instance is destructed, the destructors in that instance's inheritance chain are called, in order, from most derived to least derived.
A destructor may be executed on any thread.



И ещё масла в огонь

Finalizers (which are also called destructors)

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: alexzzzz  
Дата: 16.06.20 11:22
Оценка:
Здравствуйте, Слава, Вы писали:

С>Мне кажется, что в оригинальном вопросе у вас в финализаторе освобождалось что-то другое. Зачем вам финализатор, если у вас нет неуправляемых ресурсов?


Не касаясь оригинальной задачи, пример использования финализаторов без неуправляемых ресурсов — контролировать утечки из пула.

Есть пул объектов (или их дорого инициализировать, или они большие и хочется переиспользовать память в LOH). Если при выдаче из пула подписывать объект на финализацию, а при возвращении в пул отписывать, а в финализатор вставить логирование, то вызов GC.Collect+WaitForPendingFinalizers покажет, а не утекло ли у нас что-то мимо пула.
Re[7]: WPF. Финализаторы не вызываются. Утечка памяти
От: alexzzzz  
Дата: 16.06.20 11:32
Оценка: +1
Здравствуйте, takTak, Вы писали:

T>не, даже без вложенного массива комбинация деконструктора и бесконечного цикла ведёт к outofmemory,

T>хотя в finalizer программа регулярно заходит

Объекты создаются в цикле быстрее, чем поток финализации успевает обрабатывать их финализаторы, а GC не может убивать старые объекты, пока их финализаторы не отработали.
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 16.06.20 11:44
Оценка:
T>>не, даже без вложенного массива комбинация деконструктора и бесконечного цикла ведёт к outofmemory,
T>>хотя в finalizer программа регулярно заходит

A>Объекты создаются в цикле быстрее, чем поток финализации успевает обрабатывать их финализаторы, а GC не может убивать старые объекты, пока их финализаторы не отработали.


так проблема для меня лично не столько в этом, а в том, что деструкторы больших по размеру объектов при всём этом без проблем работают : получается противоречивое поведение, когда программа ведёт себя различно в зависимости лишь от разницы в размере данных
Re[9]: WPF. Финализаторы не вызываются. Утечка памяти
От: alexzzzz  
Дата: 16.06.20 12:11
Оценка:
Здравствуйте, takTak, Вы писали:

A>>Объекты создаются в цикле быстрее, чем поток финализации успевает обрабатывать их финализаторы, а GC не может убивать старые объекты, пока их финализаторы не отработали.

T>так проблема для меня лично не столько в этом, а в том, что деструкторы больших по размеру объектов при всём этом без проблем работают

Повод измерить и сравнить скорость выделения 10кб в нулевом поколении и 100кб в large object heap. Если во втором случае заметно дольше, то финализаторы успевают отрабатывать.

T>>> получается противоречивое поведение, когда программа ведёт себя различно в зависимости лишь от разницы в размере данных


Это очевидная зависимость. Выдели на стеке буфер в мегабайт, а потом в десять мегабайт. Во втором случае будет StackOverflow. Ну, сам виноват, не уследил за размерами. И конечно большие объёмы данных обрабатывать дольше, чем маленькие ― скорость работы программы не может не отличаться.
Отредактировано 16.06.2020 12:13 alexzzzz . Предыдущая версия . Еще …
Отредактировано 16.06.2020 12:12 alexzzzz . Предыдущая версия .
Re[10]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 16.06.20 12:18
Оценка:
A>>>Объекты создаются в цикле быстрее, чем поток финализации успевает обрабатывать их финализаторы, а GC не может убивать старые объекты, пока их финализаторы не отработали.
T>>так проблема для меня лично не столько в этом, а в том, что деструкторы больших по размеру объектов при всём этом без проблем работают

A>Повод измерить и сравнить скорость выделения 10кб в нулевом поколении и 100кб в large object heap. Если во втором случае заметно дольше, то финализаторы успевают отрабатывать.


T>>>> получается противоречивое поведение, когда программа ведёт себя различно в зависимости лишь от разницы в размере данных


A>Это очевидная зависимость. Выдели на стеке буфер в мегабайт, а потом в десять мегабайт. Во втором случае будет StackOverflow. Ну, сам виноват, не уследил за размерами. И конечно большие объёмы данных обрабатывать дольше, чем маленькие ― скорость работы программы не может не отличаться.


речь ж не о скорости, а о том, что программа принципиально работает различно в зависисмости лишь от небольшой разницы в размере данных: 85к и меньше — не работает, 85к и больше(это даже не один мегабайт, карл!) — работает
Re[11]: WPF. Финализаторы не вызываются. Утечка памяти
От: alexzzzz  
Дата: 16.06.20 12:24
Оценка: +1
Здравствуйте, takTak, Вы писали:

T>речь ж не о скорости, а о том, что программа принципиально работает различно в зависисмости лишь от небольшой разницы в размере данных: 85к и меньше — не работает, 85к и больше(это даже не один мегабайт, карл!) — работает


На стеке тоже точное количество свободного места: буфер байтом меньше ― всё работает, байтом больше ― всё вылетает к чертям. Ошибка в индексе массива всего на единицу вызывает IndexOutOfRangeException. Замена +1 на -1 может перевернуть изображение в окне вверх ногами и т.д. Наверняка можно придумать такой специальный сценарий, где OutOfMemory будет вылетать или не вылетать в зависимости от длины имени какой-нибудь переменной в коде.
Re[12]: WPF. Финализаторы не вызываются. Утечка памяти
От: takTak  
Дата: 16.06.20 12:35
Оценка:
T>>речь ж не о скорости, а о том, что программа принципиально работает различно в зависисмости лишь от небольшой разницы в размере данных: 85к и меньше — не работает, 85к и больше(это даже не один мегабайт, карл!) — работает

A>На стеке тоже точное количество свободного места: буфер байтом меньше ― всё работает, байтом больше ― всё вылетает к чертям. Ошибка в индексе массива всего на единицу вызывает IndexOutOfRangeException. Замена +1 на -1 может перевернуть изображение в окне вверх ногами и т.д. Наверняка можно придумать такой специальный сценарий, где OutOfMemory будет вылетать или не вылетать в зависимости от длины имени какой-нибудь переменной в коде.


это было бы справедливо, если бы в .NET не было так называемого автоматического управления памяти, но оно якобы есть!
Re[13]: WPF. Финализаторы не вызываются. Утечка памяти
От: alexzzzz  
Дата: 16.06.20 12:44
Оценка:
Здравствуйте, takTak, Вы писали:

T>это было бы справедливо, если бы в .NET не было так называемого автоматического управления памяти, но оно якобы есть!


Управление есть, но сделать неправильно и всё сломать можно всегда, и это предусмотрено: кто-то же добавил OutOfMemoryException в список исключений Это при том, что суть сборщика мусора ― имитировать на устройстве бесконечное количество памяти.
Отредактировано 16.06.2020 12:49 alexzzzz . Предыдущая версия . Еще …
Отредактировано 16.06.2020 12:49 alexzzzz . Предыдущая версия .
Re[13]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 11:01
Оценка:
НС>Для неуправляемых ресурсов и умеющих ими правильно пользоваться.

Почему недостаточно очистки неуправляемых ресурсов в методе IDisposable.Dispose() ?
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[14]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 17.06.20 11:04
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Почему недостаточно очистки неуправляемых ресурсов в методе IDisposable.Dispose() ?


Потому что можно забыть позвать Dispose
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[15]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 11:24
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, igor-booch, Вы писали:


IB>>Почему недостаточно очистки неуправляемых ресурсов в методе IDisposable.Dispose() ?


НС>Потому что можно забыть позвать Dispose


Похоже на архитектурный кастыль, причем плохой, учитывая что
1) можно добавить неудачный финализатор и получить утечку памяти или OutOfMemoryException
2) финализатор может вызваться неизвестно когда
или вообще не вызваться (в этом случае получаем дополнительно п. 1)
3) финализаторы снижают производительность

Лучше при тестировании огребсти проблем с не вызванным Dispose, чем на продакшене получать плавающие ошибки.
Если финализаторы работают так плохо, я бы вообще их убрал из языка и тем более из паттерна Dispose
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 11:31
Оценка:
С>>Мне кажется, что в оригинальном вопросе у вас в финализаторе освобождалось что-то другое. Зачем вам финализатор, если у вас нет неуправляемых ресурсов?

A>Не касаясь оригинальной задачи, пример использования финализаторов без неуправляемых ресурсов — контролировать утечки из пула.


У меня отписка слабого хендлера от события, как советуют здесь (Решение 3: Отписка от события в финализаторе)
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Отредактировано 17.06.2020 12:46 igor-booch . Предыдущая версия .
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: valker  
Дата: 17.06.20 11:39
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Это модельное (не реальное приложение). Я его создал, что хоть как-то продемонстрировать проблему. В реальной приложении финализатор не пустой и нет бесконечных циклов в конструкторе, но утечка памяти такая же.


Что из этого есть в вашем реальном приложении:
?
Отредактировано 17.06.2020 11:45 valker . Предыдущая версия .
Re[16]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.06.20 12:08
Оценка:
Здравствуйте, igor-booch, Вы писали:



IB>Лучше при тестировании огребсти проблем с не вызванным Dispose, чем на продакшене получать плавающие ошибки.

IB>Если финализаторы работают так плохо, я бы вообще их убрал из языка и тем более из паттерна Dispose

Финализаторы ратотают нормально. Просто в 99% достаточно using с Dispose
https://habr.com/ru/post/89720/


public void Dispose()
    {
        this.CloseHandle();
        GC.SuppressFinalize(this);//Это гарантирует, что финализатор объекта вызываться не будет.
    }


Но не всегда можно вызвать Dispose, а освободить ресурсы необходимо.
и солнце б утром не вставало, когда бы не было меня
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 12:42
Оценка:
V>Что из этого есть в вашем реальном приложении:
V> V>?

Финализатор с отпиской слабого хендлера от события как советуют здесь (Решение 3: Отписка от события в финализаторе)
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Отредактировано 17.06.2020 12:46 igor-booch . Предыдущая версия . Еще …
Отредактировано 17.06.2020 12:46 igor-booch . Предыдущая версия .
Re[17]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 13:10
Оценка:
S>Но не всегда можно вызвать Dispose, а освободить ресурсы необходимо.
Приведите пример, когда нельзя вызвать Dispose
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[18]: WPF. Финализаторы не вызываются. Утечка памяти
От: pilgrim_ Россия  
Дата: 17.06.20 14:09
Оценка:
Здравствуйте, igor-booch, Вы писали:


S>>Но не всегда можно вызвать Dispose, а освободить ресурсы необходимо.

IB>Приведите пример, когда нельзя вызвать Dispose

SafeHandle

public abstract class SafeHandle : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, IDisposable
{
...
~SafeHandle ();
}


class Unmanaged
{
    public static SafeHandle OpenResource(string resourceName);
}

class ResourceHolder : IDisposable
{
    SafeHandle _rsrcHandle;

    public ResourceHolder()
    {
        _rsrcHandle = Unmanaged.OpenResource();

        //вызов какого-то метода, который может бросить exception
        throw new SomeException();
    }

    public void Dispose()
    {
        _rsrcHandle.Dispose();
    }
}

...
using (var r = new ResourceHolder())
{
}
//Dispose вызван не будет, но остается надежда на вызов Finalize (~SafeHandle).


Могло бы решиться обкладыванием где нужно try/catch и там вызывать Dispose, но так не делают, код превратится в кашу.
Re[18]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.06.20 14:59
Оценка:
Здравствуйте, igor-booch, Вы писали:


S>>Но не всегда можно вызвать Dispose, а освободить ресурсы необходимо.

IB>Приведите пример, когда нельзя вызвать Dispose

Ну например возвращаешь в функции диспозабле объект, а тот кто получает и не знает, что он Dispose и проверку не производит, а может и не нужно вызывать Dispose и передавать еще дальше
Ты этим не управляешь.
А создатель объекта и не знает когда перестанут им пользоваться
и солнце б утром не вставало, когда бы не было меня
Re[13]: WPF. Финализаторы не вызываются. Утечка памяти
От: Sharowarsheg  
Дата: 17.06.20 15:10
Оценка:
Здравствуйте, takTak, Вы писали:

T>это было бы справедливо, если бы в .NET не было так называемого автоматического управления памяти, но оно якобы есть!


Автоматическое управление памятью — это именно оно и есть, автоматическое управление памятью. Оно автоматически управляет памятью, а не чудеса творит. Как в бачке унитаза автоматическое управление уровнем воды. Оно вообще-то работает, но если поставить унитаз бачком под Ниагарский водопад, то бачок переполнится, несмотря на исправное и работающее автоматическое управление.
Re[16]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 17.06.20 15:35
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Похоже на архитектурный кастыль,


В мире нет почти ничего идеального.

IB>1) можно добавить неудачный финализатор и получить утечку памяти или OutOfMemoryException


Поэтому не надо использовать финализаторы, если не очень хорошо знаешь как они работают. Используй SafeHandle сотоварищи и не надо будет самому никаких финализаторов писать.

IB>2) финализатор может вызваться неизвестно когда

IB>или вообще не вызваться (в этом случае получаем дополнительно п. 1)
IB>3) финализаторы снижают производительность

Это прямое следствие использования асинхронного GC. Лучше пока никто не придумал.

IB>Если финализаторы работают так плохо,


Они нормально работают если правильно их использовать.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[19]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 16:31
Оценка:
_>Могло бы решиться обкладыванием где нужно try/catch и там вызывать Dispose, но так не делают, код превратится в кашу.

Где здесь каша:

class Unmanaged
{
    public static SafeHandle OpenResource(string resourceName);
}

class ResourceHolder : IDisposable
{
    SafeHandle _rsrcHandle;

    public ResourceHolder()
    {
    bool initialized = false;
    try
    {
        _rsrcHandle = Unmanaged.OpenResource();
    
        //вызов какого-то метода, который может бросить exception

         initialized = true;
    }
    finally
    {
        if (!initialized) 
            _rsrcHandle.Dispose();
    }
    }

    public void Dispose()
    {
        _rsrcHandle.Dispose();
    }
}

...
using (var r = new ResourceHolder())
{
}



А здесь?:

class Unmanaged
{
    public static SafeHandle OpenResource(string resourceName);
}

class ResourceHolder : IDisposable
{
    SafeHandle _rsrcHandle;

    public ResourceHolder()
    {
    }

    public Initialize()
    {
        _rsrcHandle = Unmanaged.OpenResource();
    }

    public void Dispose()
    {
        _rsrcHandle.Dispose();
    }
}

...
using (var r = new ResourceHolder())
{
    r.Initialize();
}
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[20]: WPF. Финализаторы не вызываются. Утечка памяти
От: pilgrim_ Россия  
Дата: 17.06.20 16:43
Оценка:
Здравствуйте, igor-booch, Вы писали:

_>>Могло бы решиться обкладыванием где нужно try/catch и там вызывать Dispose, но так не делают, код превратится в кашу.


IB>Где здесь каша:


Добавь еще 5-10 таких полей, и будет каша.
Я же не сказал что это невозможно, я указал что так не делают, обычно, и типичный код — такой какой я привел
В частных случаях да, когда железно прям щас нужно освободить ресурс — да, так имеет смысл делать.

ps: ты же сам выбрал "ленивый" способ отписки от событий в Finalize , чем Dispose не устроил?
Re[21]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 16:52
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Здравствуйте, igor-booch, Вы писали:


_>>>Могло бы решиться обкладыванием где нужно try/catch и там вызывать Dispose, но так не делают, код превратится в кашу.


IB>>Где здесь каша:


_>Добавь еще 5-10 таких полей, и будет каша.


Просто интересно как получается каша

class Unmanaged
{
    public static SafeHandle OpenResource(string resourceName);
}

class ResourceHolder : IDisposable
{
    SafeHandle _rsrcHandle;
    SafeHandle _rsrcHandle1;
    SafeHandle _rsrcHandle2;
    SafeHandle _rsrcHandle3;
    SafeHandle _rsrcHandle4;
    SafeHandle _rsrcHandle5;

    public ResourceHolder()
    {
        bool initialized = false;
        try
        {
            _rsrcHandle = Unmanaged.OpenResource();
            _rsrcHandle1 = Unmanaged.OpenResource();
            _rsrcHandle2 = Unmanaged.OpenResource();
            _rsrcHandle3 = Unmanaged.OpenResource();
            _rsrcHandle4 = Unmanaged.OpenResource();
            _rsrcHandle5 = Unmanaged.OpenResource();
    
            //вызов какого-то метода, который может бросить exception

            initialized = true;
        }
        finally
        {
            if (!initialized)
                Dispose();
        }
    }

    public void Dispose()
    {
            _rsrcHandle?.Dispose();
            _rsrcHandle1?.Dispose();
            _rsrcHandle2?.Dispose();
            _rsrcHandle3?.Dispose();
            _rsrcHandle4?.Dispose();
            _rsrcHandle5?.Dispose();
    }
}

...
using (var r = new ResourceHolder())
{
}
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[21]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 17.06.20 17:17
Оценка:
_>ps: ты же сам выбрал "ленивый" способ отписки от событий в Finalize , чем Dispose не устроил?

Потому-что усложняется API. Я за простоту.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
От: Ночной Смотрящий Россия  
Дата: 18.06.20 08:43
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Финализатор с отпиской слабого хендлера от события как советуют здесь (Решение 3: Отписка от события в финализаторе)


Мой тебе совет — не стоит использовать хабр как источник технической информации.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.06.20 09:14
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, igor-booch, Вы писали:


IB>>Финализатор с отпиской слабого хендлера от события как советуют здесь (Решение 3: Отписка от события в финализаторе)


НС>Мой тебе совет — не стоит использовать хабр как источник технической информации.


Ну там описывается как отписаться от события, если на объект нет ссылок. Помню и на этом форуме про этот подход писали.
У меня в свое время была проблема с отпиской от нетовских объектов из браузера, так как в JavaScript нет финализаторов.
Кстати посмотрел на блазор
https://stackoverflow.com/questions/61683382/jsruntime-in-blazor-webassembly-blocking-dom-updates-on-first-load
Там можно инжектить

 @implements IDisposable


и вызвать отписку
public void Dispose()
{
    MessageService.Notify -= OnNotify;
}
и солнце б утром не вставало, когда бы не было меня
Re[18]: WPF. Финализаторы не вызываются. Утечка памяти
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.06.20 11:45
Оценка:
Здравствуйте, igor-booch, Вы писали:

S>>Но не всегда можно вызвать Dispose, а освободить ресурсы необходимо.

IB>Приведите пример, когда нельзя вызвать Dispose
Эмм, ну вот например как-то так:
var myFile = File.OpenWrite("C:\temp\0asdask12.txt");
Thread.Create(o=>myFile.Write(Encoding.UTF-8.GetBytes(o.ToString())).Start(myBigObject);

Где вы тут будете звать Dispose()?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 18.06.20 12:01
Оценка: :)
IB>>Приведите пример, когда нельзя вызвать Dispose
S>Эмм, ну вот например как-то так:
S>
S>var myFile = File.OpenWrite("C:\temp\0asdask12.txt");
S>Thread.Create(o=>myFile.Write(Encoding.UTF-8.GetBytes(o.ToString())).Start(myBigObject);
S>

S>Где вы тут будете звать Dispose()?

var myFile = File.OpenWrite("C:\temp\0asdask12.txt");
Thread.Create(o=>
{
    try     { myFile.Write(Encoding.UTF-8.GetBytes(o.ToString()); }
    finally { myFile.Dispose(); }
}).Start(myBigObject);
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Отредактировано 18.06.2020 12:01 igor-booch . Предыдущая версия .
Re: WPF. Финализаторы не вызываются. Утечка памяти
От: HotDog Швейцария www.denebspace.com
Дата: 19.06.20 07:38
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Условия воспроизведения:

IB>1) Visual Studio 2017
IB>2) Приложение WPF
IB>3) Запуск приложение под отладчиком
IB>4) код окна WPF

IB>Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.


Зпустил под VS2019 все работает нормально, память не растет.
Re[20]: WPF. Финализаторы не вызываются. Утечка памяти
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.06.20 08:43
Оценка:
Здравствуйте, igor-booch, Вы писали:

Открою тебе секрет зачем был придуман GС.
В С++ вручную овобождают память в куче (там есть и подсчет ссылок, и shared_ptr). Но не всегда это возможно. В COM применяли подсчет ссылок, но были циклические ссылки которые не разруливались.
Объектом могут владеть множество других объектов, и нужно освобождать ресурсы когда ссылок на них нет.
и солнце б утром не вставало, когда бы не было меня
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
От: igor-booch Россия  
Дата: 19.06.20 17:49
Оценка:
Здравствуйте, HotDog, Вы писали:

HD>Здравствуйте, igor-booch, Вы писали:


IB>>Условия воспроизведения:

IB>>1) Visual Studio 2017
IB>>2) Приложение WPF
IB>>3) Запуск приложение под отладчиком
IB>>4) код окна WPF

IB>>Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.


HD>Зпустил под VS2019 все работает нормально, память не растет.

У меня в 2019 тоже раблтает
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.