2014-11-25 5 views
1

У меня довольно большое приложение, написанное на VB.NET, которое, похоже, страдает от утечки памяти того или иного типа. Несколько раз в день, у меня есть экземпляры этого приложения, которые разбиваются (казалось бы, случайным образом, но всегда после почти целых суток). Я искал и читал много форумов и даже вопросы, заданные здесь в разделе «Переполнение стека» по этой конкретной проблеме. Я определил, что это связано с утечкой памяти и обычно указывает на то, что ручки превышают 10000 или объекты, превышающие лимит.Ошибка создания Window Handle (VB.NET)

Я загрузил библиотеку памяти и использовал ее для поиска и исправления нескольких утечек памяти в программе, но это, похоже, не замедляло ежедневное число сбоев. Моя программа использует глобальную ловушку ошибок для регистрации этих событий и хранения информации о них в базе данных. У меня теперь есть данные за 2 месяца, но сообщение об ошибке на самом деле не помогает мне указывать в каком-либо направлении. Недавно я добавил способность этой глобальной ловушки ошибок регистрировать дескрипторы, которые имеет приложение, и до сих пор он был намного ниже порога дескриптора 10 000. Обычно это меньше 1000.

длинный рассказ короткий, мой вопрос в этом. Есть ли способ зарегистрировать счетчик объектов GDI, чтобы я мог определить, вызвало ли это сбой моей программы? Существуют ли другие «объекты», которые могут вызвать утечку памяти и потерю крушения, помимо этих двух, и могу ли я зарегистрировать их каким-то образом?

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

Немного больше информации о моей программе и окружающей среде. В основном это работает на 64-разрядных машинах Windows 7 (хотя некоторые Vista и XP-машины присутствуют), он работает на платформе .NET 4.0. Проект состоит из нескольких сотен форм, классов и пользовательских элементов управления (построенных специально для этого проекта). Я использую профилировщик памяти .NET 4.6 для проверки утечек памяти. Я запускаю то, что я считаю наиболее ресурсоемкими операциями на моем компьютере более часа (открытие и последующее закрытие многих экранов, хруст гигабайтов данных и т. Д.) При просмотре ресурсов в диспетчере задач (ручки, нитки, USER Objects, и GDI Objects), но ни один из них не переходят 1000.

Вот копия одного из журналов от события аварии:

Loaded Assembly: GlobalFuncs, Version=1.0.3391.14822, Culture=neutral, PublicKeyToken=null 
Loaded Assembly: Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
Loaded Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d 
Loaded Assembly: SQL Database, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
Loaded Assembly: System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
Loaded Assembly: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
Loaded Assembly: System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
Loaded Assembly: System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 
Loaded Assembly: System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Speech, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 
Loaded Assembly: System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Loaded Assembly: System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 

OS Name:   Microsoft Windows 7 Professional 
OS Version:  6.1.7601.65536 
OS Platform:  x64 
Physical Memory: 1.91GB/3.90GB (Free/Total) 
Virtual Memory: 1.66GB/2.00GB (Free/Total) 

Error Output: 
System.ComponentModel.Win32Exception (0x80004005): Error creating window handle. 
    at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp) 
    at System.Windows.Forms.Control.CreateHandle() 
    at System.Windows.Forms.TextBoxBase.CreateHandle() 
    at System.Windows.Forms.Control.get_Handle() 
    at System.Windows.Forms.RichTextBox.get_TextLength() 
    at System.Windows.Forms.TextBoxBase.AdjustSelectionStartAndEnd(Int32 selStart, Int32 selLength, Int32& start, Int32& end, Int32 textLen) 
    at System.Windows.Forms.TextBoxBase.GetSelectionStartAndLength(Int32& start, Int32& length) 
    at System.Windows.Forms.TextBoxBase.AppendText(String text) 
    at SWOT.My.MyApplication.ShowDebugOutput(Exception ex) 
    at SWOT.My.MyApplication.app_ThreadException(Object sender, ThreadExceptionEventArgs e) 
    at System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception t) 
    at System.Windows.Forms.Control.WndProcException(Exception e) 
    at System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(Exception e) 
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(ApplicationContext context) 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() 
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() 

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

+0

Я хотел бы добавить, что я был в состоянии войти счетчик ручки с помощью счетчика производительности Microsoft. И.Е. [ 'код'] = PerfCounter PerformanceCounter [код] PerfCount.CategoryName = "Процесс" [код] PerfCount.CounterName = "Ручка графа" [код] PerfCount.NextValue() – CrazyC

+0

К сожалению о форматировании, не знаю, как я думаю, использовать мини-уценку. LOL – CrazyC

+1

Если вам понадобится день для вашего приложения, а затем смотреть его на час, конечно, недостаточно долго. Высокие шансы, что вы регистрируете неправильный счетчик ручек, реальный не так-то легко добраться. Ошибка всегда одна и та же, вызывая Controls.Clear() или Controls.Remove/At() и не удаляя удаленные элементы управления. И вам нужно поговорить с пользователем, просто попросите его запустить Task Manager для вас. Кроме того, куча, из которой выделены окна, является общим ресурсом с другими процессами, которые запускаются на рабочем столе. Таким образом, технически возможно, чтобы еще одна пара обрушителей вышла из строя. –

ответ

-1

Основываясь на том факте, что состояние выхода ошибки имеет довольно много памяти (более 1 ГБ), а сообщение об ошибке «Ошибка создания дескриптора окна», я подозреваю, что ваше приложение сталкивается с проблемой, не освобождая дескрипторы , а не освобождать память. Наиболее вероятной причиной не освобождения ручек является использование вызовов P/Invoke. Вы можете просто найти свой код для Declare и DllImport, чтобы узнать, действительно ли вы используете какие-либо функции P/Invoke. Если да, вам нужно будет провести подробный обзор каждой функции, которую вы вызываете, и если она вернет все ручки (через или SafeHandle-derived classes). Если какой-либо из этих вызовов создает Handle - особенно дескриптор окна (часто сокращается как hWnd), тогда вам нужно проверить, что ваш код освобождает hWnd.

Если вы не используете DllImport/P/Invoke кода, то скорее всего, вы вызываете один косвенно через управляемый код, такие как создание нового System.Windows.Forms.Form или System.Windows.Forms.Control -derived класса (который также создает дескриптор окна), а не не вызывая Закройте или удалите его. Есть и другие вещи, которые создают ручки, но они приходят на ум.

+0

Оставьте комментарий, почему этот ответ был отклонен, чтобы я мог узнать, где я ошибся, и улучшить ответ для всех! –

+0

Будучи в основном самоучкой в ​​VB.NET, я не совсем уверен, что вы подразумеваете под функцией win32, которая возвращает IntPtr (я буду google и попытаюсь изучить ее). Не уверен, кто проголосовал за ваш ответ, но я приму свой вклад и посмотрю, есть ли что-нибудь, что поможет в моей конкретной ситуации. Я обязательно вернусь и проголосую за ваш ответ, если это поможет. – CrazyC

+0

Мне может понадобиться несколько указателей, чтобы понять, куда вы меня ведете. Итак, вы просите меня преобразовать IntPtr в мой код в производный класс safehandle, чтобы MDA (в частности, дескриптор выпуска не удалось MDA) смог зафиксировать эту ошибку и сообщить об этом мне? Является ли этот конкретный MDA уже активным по умолчанию, но не может поймать эти ошибки, если только ручки не имеют тип safehandle? Я не думаю, что я прямо вызываю Invokes в моей программе (но, вероятно, косвенно). Наверное, сейчас я немного над головой, но так мы учимся плавать прямо? – CrazyC

-1

У меня было то же самое сообщение об ошибке и не уверен, что не так точно!, Но все же я хотел бы рассказать, как это было решено ...

я не делал ничего особенного, но как заявил Скотт форма звала создав новый экземпляр и метод Form.show(), когда кнопка нажата из основной формы, что я сделал вместо того, чтобы открывать форму путем события click, я просто дал форму, вызывающую ошибку непосредственно в качестве формы запуска, и попытался запустить. форма не была загружена, ни сообщение об ошибке!, я вернулся и снова изменил форму запуска обратно в основную форму и побежал, тогда это было волшебство, когда я нажал кнопку, в которую была загружена форма, без какого-либо сообщения об ошибке !!!.

не знаю, что изменилось позади, но до сих пор все хорошо в настоящее время ......

 Смежные вопросы

  • Нет связанных вопросов^_^