Условия воспроизведения:
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. Финализаторы не вызываются. Утечка памяти
IB>Что присходит: IB>Этот код отваливается с OutOfMemoryException. Финализаторы Item() не вызываются.
IB>В моем реальном WPF приложении утечка памяти просходит без отладки и в более мягких условиях, но проявления те же: финализаторы не вызываются, происходит учечка памяти.
забавно: если деконструктор
~Item()
{
}
полностью убрать, то всё работает
Re: WPF. Финализаторы не вызываются. Утечка памяти
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. Финализаторы не вызываются. Утечка памяти
T>>забавно: если деконструктор T>>полностью убрать, то всё работает
НС>Чего ж тут забавного? Объекты перестает держать fqueue и GC прекрасно справляется со сборкой.
вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,
и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,
если же взять _bytes = new byte[10000], то происходит outOfMemory
Re[4]: WPF. Финализаторы не вызываются. Утечка памяти
Здравствуйте, takTak, Вы писали:
T>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,
Он не может там подчистить без вызова финализаторов, а это потенциально долго.
T>и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,
100К попадает в LOH, там несколько другие алгоритмы.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: WPF. Финализаторы не вызываются. Утечка памяти
T>>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,
НС>Он не может там подчистить без вызова финализаторов, а это потенциально долго.
если бы в Item не было вы массива, то всё бы тоже работало, даже с наследованием,
проблема в сочетании деконструктора и небольшого массива внутри объекта
T>>и если использовать больший массив _bytes = new byte[100000], то всё, как ожидается и работает,
НС>100К попадает в LOH, там несколько другие алгоритмы.
да, согласен, там другой алгоритм, и он справляется
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
T>>>вообще-то GC сам должен заглядывать во fqueue и всё там подчищать,
НС>>Он не может там подчистить без вызова финализаторов, а это потенциально долго.
T>если бы в Item не было вы массива, то всё бы тоже работало, даже с наследованием, T>проблема в сочетании деконструктора и небольшого массива внутри объекта
не, даже без вложенного массива комбинация деконструктора и бесконечного цикла ведёт к outofmemory,
хотя в finalizer программа регулярно заходит
Re[3]: WPF. Финализаторы не вызываются. Утечка памяти
Здравствуйте, takTak, Вы писали: T>единственное, что всё меняет: это наличие или отсутствие деконструктора
Деконструктор в дотнет — это метод Deconstruct. Он применяется для паттерн-матчинга и для деконструирующих присваиваний.
А то, о чём вы говорите, называется финализатором.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: WPF. Финализаторы не вызываются. Утечка памяти
T>>единственное, что всё меняет: это наличие или отсутствие деконструктора S>Деконструктор в дотнет — это метод Deconstruct. Он применяется для паттерн-матчинга и для деконструирующих присваиваний. S>А то, о чём вы говорите, называется финализатором.
забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор",
"финализатор" на https://ru.wiktionary.org/ не находится
Re[5]: WPF. Финализаторы не вызываются. Утечка памяти
Здравствуйте, takTak, Вы писали: T>забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор", T>"финализатор" на https://ru.wiktionary.org/ не находится
Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: WPF. Финализаторы не вызываются. Утечка памяти
T>>забавно: в русском языке есть заимствовование "конструктор", так вот антонимом ему является не "деконструктор", а "деструктор", T>>"финализатор" на https://ru.wiktionary.org/ не находится S>Мы говорим не о литературном русском языке, а о терминологии производителя. Деструкторов в CLR нет, т.к. деструктор подразумевает детерминистическую финализацию.
если обратно к нашим баранам, то
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. Финализаторы не вызываются. Утечка памяти
T>>проблема в сочетании деконструктора и небольшого массива внутри объекта
НС>Нет. Проблема в большом количестве финализаторов и быстром выжирании пулов поколений.
ну да, похоже на такое...
как вообще происходит "быстрое выжирание пулов поколений" и почему gc.collect этому "выжиранию" препятствует?
Re[8]: WPF. Финализаторы не вызываются. Утечка памяти