Отладка исключения OutOfMemory с помощью WinDbg и wpr. Почему эти символы показаны как ?!? - перепутал .net?

Я пытался понять, почему мы получаем OOM под Citrix — Windows 10, хотя на обычных машинах этого не происходит. Наше приложение сочетает в себе собственные плагины C++, C# и веб-браузера. Контейнер .net.

Подробности: Windows 10 Версия 18363 MP (2 процедуры) Бесплатная совместимость с x86 Продукт: WinNt, пакет: SingleUserTS 18362.1.wow64fre.19h1_release.190318-1202

2920000 730d0000   clr        (pdb symbols)          
    Loaded symbol image file: clr.dll
    Image path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    Image name: clr.dll
    Browse all global symbols  functions  data
    Timestamp:        Wed Aug  5 03:06:56 2020 (5F2A0630)
    CheckSum:         007B81A2
    ImageSize:        007B0000
    File version:     4.8.4250.0
    Product version:  4.0.30319.0
    File flags:       8 (Mask 3F) Private
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    Information from resource tables:
        CompanyName:      Microsoft Corporation
        ProductName:      Microsoft® .NET Framework
        InternalName:     clr.dll
        OriginalFilename: clr.dll
        ProductVersion:   4.8.4250.0
        FileVersion:      4.8.4250.0 built by: NET48REL1LAST_C
        PrivateBuild:     DDBLD342B
        FileDescription:  Microsoft .NET Runtime Common Language Runtime - WorkStation
        LegalCopyright:   © Microsoft Corporation.  All rights reserved.
        Comments:         Flavor=Retail

Исключение на WinDbg

FAULTING_THREAD:  ffffffff

STACK_TEXT:  
011dd108 6e06611c PresentationCore_ni!System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap+0x47c


STACK_COMMAND:  !D:\WindDbg\windbg\x86\sym\SOS_x86_x86_4.8.4250.00.dll\5F2A06307b0000\SOS_x86_x86_4.8.4250.00.dll.pe 0x26b56e80 ; ** Pseudo Context ** ManagedPseudo ** Value: 12630c10 ** ; kb

MODULE_NAME: Unknown_Module

IMAGE_NAME:  Unknown_Image

FAILURE_BUCKET_ID:  CLR_EXCEPTION_System.OutOfMemoryException_8007000e_nexus.framework.healthcare.exe!unknown_error_in_process

OS_VERSION:  10.0.18362.1

BUILDLAB_STR:  19h1_release

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

FAILURE_ID_HASH:  {196470ae-a638-36df-be48-e73b2df228f8}
 *** Followup info cannot be found !!! Please contact...

Приходит ООМ, поднимается на .Net и иногда приложение продолжает работать! В других случаях я получаю исключение уже при использовании памяти ~ 700 МБ в диспетчере задач, что действительно странно.

Получив исключение, мне удалось запустить PerfView и форсировать GC, уменьшив его с › 750 МБ до 350 МБ в диспетчере задач. Почему-то у меня такое ощущение, что GC работает не так, как ожидалось под Citrix.

PerfView показывает на самом деле очень небольшое количество оставшихся объектов по сравнению с началом. PerfView Diff

Также Vmap показывает много блоков размером ~ 75 МБ в куче - я думаю, это из .Net, но '?!?' Меня беспокоит. Мое предположение основано на том факте, что я принудительно включил сборщик мусора в PerfView, и эти блоки исчезли. Кроме того, блоки WPF, которые я видел в WPA, имеют тот же размер wird, что и на этом?!? блокировать. Это не может быть совпадением.

Vmap

В куче почти нет фрагментации: Куча фрагментов

Я даже пытался использовать wpr, чтобы выяснить, что вызывает ошибку, и я вижу, что WPF на .net выделяет блоки ~ 75 МБ, и это странно?!? также - я предполагаю, что это код с перекодировкой. У меня есть почти все доступные символы, и все еще не повезло - ?1? остается там. Возможно, wpr не сохранял информацию .Net - мне нужно будет попробовать с профилями, но у меня нет постоянного доступа к компьютеру.

Это представления WPA: WPF Блоки Странные блоки Wpr

Вот что Windbg говорит мне о памяти:

WinDbg

Как видите, .net использует только около 147 МБ этой части, остальные 200 МБ я не уверен. Виртуаллок? Я думал, что они пойдут в часть Heap.

Зарезервированные 200Мб тоже под большим вопросом, попробую выяснить зачем он там.

dll не может быть уменьшено - они нужны нам все, особенно если пользователь открывает много плагинов одновременно.

Интересно, является ли это известной проблемой Citrix. Могу ли я что-нибудь еще сделать, чтобы проверить, почему мы получаем этот OOM, хотя у нас все еще есть 175 МБ свободного места? Я не могу понять, почему нашему приложению нужно больше, чем это сразу. Мы не показываем большие картинки и видео.

Я проверил объекты GDI/Handles/User, и все в порядке. Они не высокие.

У меня была одна идея, но я еще не пробовал: изменить настройки GC на Workstation - Concurrent, чтобы посмотреть, что произойдет. Не уверен, что это поможет.

Это стек:

0:000> k
 # ChildEBP RetAddr  
00 011dbd40 75def159 ntdll!NtWaitForSingleObject+0xc
01 011dbdb4 725e3370 KERNELBASE!WaitForSingleObjectEx+0x99
02 011dbde4 725e33cc clr!CLREventWaitHelper2+0x33
03 011dbe34 725e3319 clr!CLREventWaitHelper+0x2a
04 011dbe6c 725e333b clr!CLREventBase::WaitEx+0x14b
05 011dbe84 728d0125 clr!CLREventBase::Wait+0x1a
06 011dbef0 728d023a clr!Thread::WaitSuspendEventsHelper+0x8a
07 011dbf04 728ce36a clr!Thread::WaitSuspendEvents+0x14
08 011dbf1c 7267bcae clr!Thread::RareEnablePreemptiveGC+0x98
09 011dbf60 72b33ac5 clr!Thread::RareDisablePreemptiveGC+0x115
0a 011dbf84 72b2b333 clr!GCHolderEEInterface<0,1,1>::~GCHolderEEInterface<0,1,1>+0x61
0b 011dbfb8 72b2b4ea clr!Debugger::SendExceptionHelperAndBlock+0x133
0c 011dc030 72b2b86c clr!Debugger::SendExceptionEventsWorker+0x130
0d 011dc080 72b2b9d9 clr!Debugger::SendException+0x120
0e 011dc0a8 728841fa clr!Debugger::FirstChanceManagedException+0x19
0f 011dc0c4 726c15f4 clr!EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException+0x31
10 011dc140 725e0754 clr!COMPlusThrowCallback+0x311
11 011dc40c 725e085a clr!Thread::StackWalkFramesEx+0x92
12 011dc740 726c1f01 clr!Thread::StackWalkFrames+0x9d
13 011dc8f0 726c238f clr!CPFH_RealFirstPassHandler+0x68e
14 011dc940 726c245a clr!CPFH_FirstPassHandler+0x119
15 011dc96c 72885fc7 clr!COMPlusFrameHandler+0x15d
16 011dc98c 770a8e72 clr!COMPlusFrameHandlerRevCom+0x17
17 011dc9b0 770a8e44 ntdll!ExecuteHandler2+0x26
18 011dca78 770942d6 ntdll!ExecuteHandler+0x24
19 011dca78 75e044c2 ntdll!KiUserExceptionDispatcher+0x26
1a 011dcf9c 726c28f0 KERNELBASE!RaiseException+0x62
1b 011dd038 726c3796 clr!RaiseTheExceptionInternalOnly+0x230
1c 011dd100 6e06611c clr!IL_Throw+0x146
WARNING: Stack unwind information not available. Following frames may be wrong.
1d 011dd1f0 6e04ff49 PresentationCore_ni+0x26611c
1e 011dd230 6e04feb2 PresentationCore_ni+0x24ff49
1f 011dd23c 6e04fe89 PresentationCore_ni+0x24feb2
20 011dd24c 6e04e3f0 PresentationCore_ni+0x24fe89
21 011dd390 6e04d910 PresentationCore_ni+0x24e3f0
22 011dd3cc 153582a3 PresentationCore_ni+0x24d910
23 011dd3dc 24be9b87 0x153582a3
24 011dd408 24be9a4d 0x24be9b87
25 011dd440 24be9986 0x24be9a4d
26 011dd458 24be96dd 0x24be9986
27 011dd470 1defd0c2 0x24be96dd
28 011dd4c4 1defcdb8 0x1defd0c2
29 011dd4d0 05de45c1 0x1defcdb8
2a 011dd51c 13ac31bb 0x5de45c1
2b 011dd52c 05de1fd8 0x13ac31bb
2c 011dd554 05de1e38 0x5de1fd8
2d 011dd56c 14a46136 0x5de1e38
2e 011dd588 14a46007 0x14a46136
2f 011dd5c0 725cf404 0x14a46007
30 011dd5e8 72694073 clr!COMToCLRDispatchHelper+0x6b
31 011dd644 0164e631 clr!COMToCLRWorker+0x4d5
32 011dd670 5b03e711 0x164e631
33 011dd6b0 5b03eeec NXIMFServer+0x7e711
34 011dd6f8 5afc480b NXIMFServer+0x7eeec
35 011dd79c 5b03aee0 NXIMFServer+0x480b
36 011dd82c 5b03ad7c NXIMFServer+0x7aee0
37 011dd8fc 5b03b147 NXIMFServer+0x7ad7c
38 011dd984 5b03cc47 NXIMFServer+0x7b147
39 011dd9bc 5b03afee NXIMFServer+0x7cc47
3a 011dda0c 760b829f NXIMFServer+0x7afee
3b 011dda34 7609a861 oleaut32!DispCallFunc+0x16f
3c 011ddcf8 76093e8d oleaut32!CTypeInfo2::Invoke+0x631
3d 011ddd24 5b013552 oleaut32!DispInvoke+0x2d
3e 011ddd4c 69f8e057 NXIMFServer+0x53552
3f 011dde10 69f8e45e mfc140!COleDispatchDriver::InvokeHelperV+0x227 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\oledisp2.cpp @ 399] 
40 011dde30 25558ee1 mfc140!COleDispatchDriver::InvokeHelper+0x1e [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\oledisp2.cpp @ 557] 
41 011dde5c 25558e01 MFListManAX!DllUnregisterServer+0x3951
42 011ddeb8 25558a3d MFListManAX!DllUnregisterServer+0x3871
43 011dded0 69fbe19b MFListManAX!DllUnregisterServer+0x34ad
44 011ddfa0 69fbd9cd mfc140!CWnd::OnWndMsg+0x79b [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 2698] 
45 011ddfc4 69f2ade3 mfc140!CWnd::WindowProc+0x2d [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 2099] 
46 011ddfec 69fbbcd7 mfc140!COleControl::WindowProc+0x133 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\ctlcore.cpp @ 1711] 
47 011de064 69fbbf24 mfc140!AfxCallWndProc+0xb7 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 268] 
48 011de084 2556bf30 mfc140!AfxWndProc+0x34 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 417] 
49 011de0c0 753345cb MFListManAX!DllUnregisterServer+0x169a0
4a 011de0ec 753150dc user32!_InternalCallWinProc+0x2b
4b 011de1d0 7531462f user32!UserCallWinProcCheckWow+0x3ac
4c 011de208 679fe787 user32!CallWindowProcW+0x7f
4d 011de230 725cf36d ToolkitPro1631vc140!CXTPSkinManagerApiHook::OnHookCallWindowProcW+0x77
4e 011de270 079a7957 clr!PInvokeStackImbalanceHelper+0x22
4f 011de2b8 079a787a 0x79a7957
50 011de2fc 14741f41 0x79a787a
51 011de330 079a65a9 0x14741f41
52 011de338 079a6580 0x79a65a9
53 011de34c 079a7a56 0x79a6580
54 011de388 14508f10 0x79a7a56
55 011de3bc 753345cb 0x14508f10
56 011de3e8 753150dc user32!_InternalCallWinProc+0x2b
57 011de4cc 7531488d user32!UserCallWinProcCheckWow+0x3ac
58 011de530 75329f7d user32!SendMessageWorker+0x1fd
59 011de560 2555d0d9 user32!SendMessageA+0x11d
5a 011de58c 28f95acf MFListManAX!DllUnregisterServer+0x7b49
5b 011de788 12c7e319 ML3001_2G!CMFListManagerGridView::OnLButtonDblClkRowCol+0x89f
5c 011de7c8 12c683eb GX6082VC140R!CGXControl::LButtonDblClk+0xb9
5d 011de860 12cda891 GX6082VC140R!CGXGridCore::DoLButtonDblClk+0x6cb
5e 011de878 69fbdf55 GX6082VC140R!CGXGridView::OnLButtonDblClk+0x21
5f 011de94c 69fbd9cd mfc140!CWnd::OnWndMsg+0x555 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 2698] 
60 011de970 12cdb074 mfc140!CWnd::WindowProc+0x2d [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 2099] 
61 011de98c 69fbbcd7 GX6082VC140R!CGXGridView::WindowProc+0x44
62 011dea04 69fbbf24 mfc140!AfxCallWndProc+0xb7 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 268] 
63 011dea24 2556bf30 mfc140!AfxWndProc+0x34 [d:\agent\_work\3\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wincore.cpp @ 417] 
64 011dea60 753345cb MFListManAX!DllUnregisterServer+0x169a0
65 011dea8c 753150dc user32!_InternalCallWinProc+0x2b
66 011deb70 7531422e user32!UserCallWinProcCheckWow+0x3ac
67 011debe4 75314010 user32!DispatchMessageWorker+0x20e
68 011debf0 725cf36d user32!DispatchMessageW+0x10
69 011dec20 6eb374f1 clr!PInvokeStackImbalanceHelper+0x22
6a 011dec5c 6eb1b3d7 WindowsBase_ni+0xf74f1
6b 011deca4 6eb1b319 WindowsBase_ni+0xdb3d7
6c 011decb0 68782ecc WindowsBase_ni+0xdb319
6d 011decc0 68782a8a PresentationFramework_ni+0x2c2ecc
6e 011dece0 6878287e PresentationFramework_ni+0x2c2a8a
6f 011ded00 14e8e234 PresentationFramework_ni+0x2c287e
70 011ded28 016e0dff 0x14e8e234
71 011ded58 725cf036 0x16e0dff
72 011ded64 725d22da clr!CallDescrWorkerInternal+0x34
73 011dedb8 725d859b clr!CallDescrWorkerWithHandler+0x6b
74 011dee2c 7277b11b clr!MethodDescCallSite::CallTargetWorker+0x16a
75 011def50 7277b7fa clr!RunMain+0x1b3
76 011df1bc 7277b727 clr!Assembly::ExecuteMainMethod+0xf7
77 011df6a0 7277b8a8 clr!SystemDomain::ExecuteMainMethod+0x5ef
78 011df6f8 7277b9ce clr!ExecuteEXE+0x4c
79 011df738 72777305 clr!_CorExeMainInternal+0xdc
7a 011df774 7420fa84 clr!_CorExeMain+0x4d
7b 011df7ac 7477e80e mscoreei!_CorExeMain+0xd6
7c 011df7bc 74784338 mscoree!ShellShim__CorExeMain+0x9e
7d 011df7c4 76d16359 mscoree!_CorExeMain_Exported+0x8
7e 011df7d4 77087c24 kernel32!BaseThreadInitThunk+0x19
7f 011df830 77087bf4 ntdll!__RtlUserThreadStart+0x2f
80 011df840 00000000 ntdll!_RtlUserThreadStart+0x1b

И темы:

0:000> !threads
ThreadCount:      11
UnstartedThread:  0
BackgroundThread: 10
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                                                         Lock  
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 1fc8 0173da08     a6028 Preemptive  26B56FB0:00000000 01736698 1     STA System.OutOfMemoryException 26b56e80
   3    2 2c84 01782be0     2b228 Preemptive  00000000:00000000 01736698 0     MTA (Finalizer) 
   6    3 279c 06031fc8   102a228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Worker) 
   9    6 2404 0801d028   202b228 Preemptive  00000000:00000000 01736698 1     MTA 
  28   10 2298 21eddb10   a029228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Completion Port) 
  33    8 29d0 0608bde0   1029228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Worker) 
  34    7 2d08 2c5f1f10   1029228 Preemptive  26B51A60:00000000 01736698 0     MTA (Threadpool Worker) 
  35    4 1db0 21eb39c8   1029228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Worker) 
  36   11 2550 2bc2d008     a1228 Preemptive  00000000:00000000 01736698 0     Ukn 
  38    5  2a0 0d7d2090   8029228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Completion Port) 
  39    9 2010 2c502b50   8029228 Preemptive  00000000:00000000 01736698 0     MTA (Threadpool Completion Port) 

********** Редактировать ********** Итак, я искал растровые изображения:

Statistics:
      MT    Count    TotalSize Class Name
6de2a780        1           12 System.Windows.Media.Imaging.BitmapCreateOptions
6de1144c        1           20 System.Windows.UncommonField`1[[System.Windows.Media.BitmapScalingMode, PresentationCore]]
6e796fdc        2           32 System.Windows.Media.Effects.BitmapEffectState
6de11368        2           40 System.Windows.UncommonField`1[[System.Windows.Media.Effects.BitmapEffectState, PresentationCore]]
6de20d8c        2           72 System.Windows.Media.Effects.DropShadowBitmapEffect
6de0e698        6           72 System.Windows.Media.BitmapScalingMode
6de2a748        7           84 System.Windows.Media.Imaging.BitmapCacheOption
6e7968f8        1          108 System.Windows.Media.Imaging.IconBitmapDecoder
6de202d8       15          300 System.Windows.Media.Imaging.BitmapPalette
6de2d9a4       19          304 System.Windows.Media.Imaging.BitmapSource+WeakBitmapSourceEventSink
6de217d4        4          432 System.Windows.Media.Imaging.JpegBitmapDecoder
6de20650        4          720 System.Windows.Media.Imaging.ColorConvertedBitmap
6de2d0e4       55          880 System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Windows.Media.Imaging.BitmapFrame, PresentationCore]]
6de2d374       55          900 System.Windows.Media.Imaging.BitmapFrame[]
6de2d15c       55         1320 System.Collections.Generic.List`1[[System.Windows.Media.Imaging.BitmapFrame, PresentationCore]]
6de20434        9         1368 System.Windows.Media.Imaging.CachedBitmap
6de0a224       10         1400 System.Windows.Media.Imaging.UnmanagedBitmapWrapper
6de2cb5c      300         3600 System.Windows.Media.Imaging.BitmapInitialize
6de2200c       50         5400 System.Windows.Media.Imaging.PngBitmapDecoder
6de2d3e8      280         6720 System.Windows.Media.Imaging.BitmapSourceSafeMILHandle
6de2d22c       98        17640 System.Windows.Media.Imaging.BitmapFrameDecode
6de2a134      179        37232 System.Windows.Media.Imaging.BitmapImage
Total 1155 objects

Место, где я получаю OOM, не обязательно отвечает за высокое использование памяти, но в любом случае:

0:000> !pe
Exception object: 26b56e80
Exception type:   System.OutOfMemoryException
Message:          Nicht genügend Speicher verfügbar, um das Programm weiter auszuführen.
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    011DD108 6E06611C PresentationCore_ni!System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap(System.Windows.Media.Imaging.BitmapFrame, System.Windows.Media.Imaging.BitmapSourceSafeMILHandle, System.Windows.Media.Imaging.BitmapCreateOptions, System.Windows.Media.Imaging.BitmapCacheOption, System.Windows.Media.Imaging.BitmapPalette)+0x47c

StackTraceString: <none>
HResult: 8007000e
0:000> .exr -1
*** WARNING: Unable to verify checksum for PresentationCore.ni.dll
ExceptionAddress: 6e06611c (PresentationCore_ni+0x0026611c)
   ExceptionCode: e0434f4d (CLR exception)
  ExceptionFlags: 00000000
NumberParameters: 0
0:000> !clrstack
OS Thread Id: 0x1fc8 (0)
Child SP       IP Call Site
011dd058 77091e4c [HelperMethodFrame: 011dd058] 
011dd108 6e06611c System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap(System.Windows.Media.Imaging.BitmapFrame, System.Windows.Media.Imaging.BitmapSourceSafeMILHandle, System.Windows.Media.Imaging.BitmapCreateOptions, System.Windows.Media.Imaging.BitmapCacheOption, System.Windows.Media.Imaging.BitmapPalette)
011dd204 6e04ff49 System.Windows.Media.Imaging.CachedBitmap.FinalizeCreation()
011dd238 6e04feb2 System.Windows.Media.Imaging.CachedBitmap.EndInit()
011dd244 6e04fe89 System.Windows.Media.Imaging.CachedBitmap..ctor(System.Windows.Media.Imaging.BitmapSource, System.Windows.Media.Imaging.BitmapCreateOptions, System.Windows.Media.Imaging.BitmapCacheOption)
011dd25c 6e04e3f0 System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
011dd398 6e04d910 System.Windows.Media.Imaging.BitmapImage.EndInit()

Спасибо, Марко


person Marco    schedule 17.10.2020    source источник
comment
Вы вручную удаляете растровые изображения, которые используете?   -  person Gusman    schedule 17.10.2020
comment
да. я тоже проверил это. Я также проверил это на Windbg и искал растровые изображения, их около 6, и они в сумме составляют около 20 МБ. я постараюсь опубликовать его на исходный вопрос как можно скорее.   -  person Marco    schedule 17.10.2020
comment
У вас есть полные данные об исключениях .net? Stacktrace, сообщение, внутреннее исключение... Это может иметь более подробную информацию.   -  person Gusman    schedule 17.10.2020
comment
поиск Google говорит ?!? относится к коду моноджиттинга, и wpr не может декодировать такие символы, для декодирования такого символа требуется либо провайдер .net etw, либо некоторый бэкэнд il2cpp и pdb.   -  person blabb    schedule 17.10.2020
comment
@blabb: среда выполнения .NET — 4.8, а не Mono. Когда вы получаете ?!? с wpr, то, скорее всего, у вас есть много процессов с большим количеством JIT-кода, который будет генерировать для CLR Rundown больше данных, чем могут получить сконфигурированные буферы wpr, и вы потеряете значительное количество методов, которые позже потребуются для получения имен методов из выделение трассировки стека.   -  person Alois Kraus    schedule 22.10.2020
comment
@AloisKraus Спасибо за предупреждение. Я не c#er, мое внимание привлек тег windbg. так будет ли удаление этого комментария лучшим вариантом? можете ли вы перефразировать свой комментарий, чтобы описать его для OP, чтобы я мог с радостью удалить свой комментарий   -  person blabb    schedule 22.10.2020
comment
@Marco: вывод VMMap странных страниц размером 4 КБ является артефактом ваших собственных экспериментов по отладке с gflags. Обычно это защитная страница до/после выделения для обнаружения переполнения кучи C/C++. Отключите gflags для всех защитных страниц распределения, и ваше приложение не будет иметь этих защитных страниц. Это могут быть ваши растровые изображения, но это не ясно без полного дампа памяти. Вы страдаете от фрагментации памяти. У вас выделено 1,3 ГБ + 200 МБ зарезервировано и 474 МБ свободно. Но самый большой свободный блок составляет всего 152 МБ для вашего приложения x86 с небольшим адресом размером 2 ГБ.   -  person Alois Kraus    schedule 22.10.2020
comment
@AloisKraus Я буду проверять, как получить больше памяти для wpr, чтобы я мог видеть код с перекодировкой. Еще мне интересно, почему нашей программе нужно выделять больше 152 МБ. Для меня это не имеет смысла. Запись с джиттинговым кодом в моно уже была известна, но я тоже думал, что это проблема типа blabb. Спасибо / Данке   -  person Marco    schedule 22.10.2020
comment
Выполните команду wpr -start VirtualAllocation и не запускайте многие другие процессы или в качестве обходного пути, который вы можете использовать для %i в (*.dll) do ngen install %i, чтобы предотвратить вывод большого количества JIT-кода. Я думаю, что буферы для рандауна жестко закодированы в WPR, поэтому, насколько я знаю, это невозможно настроить. Вы все еще можете делать вещи с xperf, который позволяет вам начать такой сеанс Rundown с буфером приличного размера.   -  person Alois Kraus    schedule 22.10.2020


Ответы (1)


Приходит ООМ, поднимается на .Net и иногда приложение продолжает работать

Это будет только в том случае, когда

  • исключение перехватывается и обрабатывается
  • это происходит в потоке пользовательского интерфейса, и .NET отображает диалоговое окно, хотите ли вы продолжить или нет.

В других случаях я получаю исключение уже при использовании памяти ~ 700 МБ.

а) Вы можете получить исключение OOM при любом использовании памяти. Уже не научный подход к этому ООМ. б) Что такое использование памяти? Вы говорите о виртуальной памяти, памяти .NET, собственной памяти, размере рабочего набора, пиковом размере рабочего набора? Пожалуйста, ознакомьтесь с терминами и используйте правильный. В идеале также назовите инструмент, который вы использовали для его измерения.

Получив исключение, мне удалось запустить PerfView и форсировать GC, уменьшив его с › 750 МБ до 350 МБ. Почему-то у меня такое ощущение, что GC работает не так, как ожидалось под Citrix.

.NET может принять решение о сборке мусора, когда захочет. Иногда он предпочитает выполнять вычисления сборке мусора. Тот факт, что вы можете форсировать сборку мусора и уменьшить объем памяти, является для меня индикатором того, что GC в основном работает.

PerfView показывает на самом деле очень небольшое количество оставшихся объектов по сравнению с началом.

Одного объекта может быть достаточно для утечки памяти.

Также Vmap показывает много блоков ~ 75 МБ в куче - я думаю, это из .Net.

С чего вы взяли, что это из .NET? .NET не использует диспетчер кучи. Он использует диспетчер виртуальной памяти. Так что эти блоки, скорее всего, не из .NET.

В куче почти нет фрагментации

Фрагментация памяти может быть проблемой. Но зачем заботиться о фрагментации внутри нативных куч?

это странно?!? также - я предполагаю, что это код с перекодировкой

Да, это вероятно.

У меня есть почти все доступные символы, и все еще не повезло - ?1? остается там.

Символов недостаточно для отладки .NET, и большинство приложений не могут работать с .NET. Для .NET приложение должно иметь возможность обрабатывать детали работы .NET. Для WinDbg эта логика закодирована в расширении WinDbg SOS. Подробности управления памятью доступны в MSCORDACWKS.DLL.

Пока приложение не запрашивает их, оно, скорее всего, не будет поддерживать .NET.

Есть ли что-нибудь еще, что я могу сделать, чтобы проверить, почему мы получаем этот OOM, хотя у нас все еще есть 175 МБ свободного места?

Если ваше приложение хочет выделить сразу 176 МБ памяти, 175 МБ будет недостаточно. Проверьте, сколько памяти требуется вашему приложению во время сбоя.

это стек

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

Проблема

Во всем посте я пропускаю это различие между управляемым и нативным материалом. Вы смешиваете собственные команды, такие как k, для стека с управляемыми командами, такими как !threads. Вы анализируете исключение .NET с помощью собственной команды !analyze вместо управляемой команды !pe. Вы исследуете управляемое исключение OOM, но в то же время вы смотрите на фрагментацию собственных куч.

Как отлаживать

Приучите себя к тому, как работает память. Память .NET будет частью <unknown> памяти, указанной !address -summary. Однако некоторые другие библиотеки также будут использовать диспетчер виртуальной памяти и, таким образом, также будут перечислены как <unknown>. Растровые изображения являются распространенным примером.

Чтобы проанализировать память .NET, вам нужно использовать специальные команды .NET, которые поступают из расширения SOS. Используйте !dumpheap -stat и !eeheap -gc. И сделайте нам одолжение и не публикуйте результат в виде изображений. Используйте .logopen, чтобы получить текстовый вывод.

Чтобы лучше сравнить память .NET, используйте подходящий для этого инструмент. WinDbg нет. Сюда подходят такие инструменты, как JetBains dotMemory. Внутри такого сравнения отфильтруйте известные вам объекты, которые необходимо удалить.

То, что WinDbg называет кучей, является собственными кучами. Обычно они поступают из библиотеки C++.

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

  • Собственные кучи по-прежнему занимают большую часть памяти в вашем приложении. Почему? Потенциально вы можете установить точки останова при выделении памяти и проверить, кто выделяет 75-мегабайтные блоки.
  • почему вы загружаете 400 МБ DLL? Можете ли вы избавиться от некоторых?
  • почему там 200 МБ зарезервированной памяти? Кто это распределяет? По какой причине?
person Thomas Weller    schedule 17.10.2020
comment
Спасибо за комментарии. Я обновил вопрос. Использование профилировщика в производственной системе клиента невозможно, и у нас нет Citrix. Как я уже сказал, мы не получаем OOM на обычных рабочих станциях Win 10. Только под Citrix. В прошлом я видел некоторые проблемы с .net, подобные этой: docs.microsoft.com/en-us/troubleshoot/dotnet/framework/ Вот почему мне интересно, не запускается ли GC слишком поздно. - person Marco; 17.10.2020
comment
@Marco: что ты имеешь в виду под обычной Win10? 32 бит или 64 бит? Ваша программа поддерживает большие адреса? - person Thomas Weller; 17.10.2020
comment
Извините. Приложение 32-битное, эта версия не поддерживает большие адреса. когда я включаю его, он работает, однако некоторые плагины пока не могут с этим справиться, поэтому сейчас это не вариант. Винда 64 битная. Я видел несколько дампов раньше, но обычно oom происходит, когда свободно менее 20 МБ. Однажды я получил один OOM с более чем 200 бесплатными. это должно быть что-то связанное с citrix, о чем я не знаю. - person Marco; 17.10.2020