解析性能瓶颈 — 调试OutOfMemoryExceptionCLR thread pool

在前的章中,推行性测试—起步里,讲了执行性测试的为主步骤,而且于前头的事例中,通过一个2M差不多的文件文件,对比了冒泡排序和快速排序的性质之间的差异。但是当我利用一个700M轻重的文件文件进行测试的上—因为自身要了解在最为情况下零星栽排序方法的反差。原定是2G的文件文件,但是无论快排还是冒泡排序都务求让排序的多寡了是让内存当中,对于32位机,2G的数量是一个上限,因为操作系统的基石代码用掉了另外2G的地点空间—除非您利用/LARGEADDRESSAWARE这个开关,限制操作系统只行使1G底内存,而给用户态代码使用3G的空中。

https://github.com/dotnet/coreclr/issues/12357

 

 

为了重现这个题材,我们先来准备一下数据,用底两独DOS命令就可准备好这些数量了:

 

 

http://mattwarren.org/2017/04/13/The-CLR-Thread-Pool-Thread-Injection-Algorithm/

1.   dir /s /b c:\windows >
d:\test.txt

http://webcourse.cs.technion.ac.il/236635/Winter2009-2010/hw/WCFiles/2.pdf

2.   FOR /L %i IN (1,1,100) DO type
test.txt >> testdata.txt

http://joeduffyblog.com/2006/07/08/clr-thread-pool-injection-stuttering-problems/

 

https://stackoverflow.com/questions/2242260/general-number-of-threads-in-thread-pool

第一独指令将Windows文件夹里面所有子文件夹的公文列表都输出到test.txt文件里,第二只指令循环100百分之百,将test.txt文件内容充实到testdata.txt里面,这样就是好生成好几百兆大小的公文文件了。

https://en.wikipedia.org/wiki/Hill_climbing

 

https://www.codeproject.com/Articles/1182012/The-CLR-Thread-Pool-Thread-Injection-Algorithm

数据变动好了下,使用实践性测试—起步贴出来的程序执行一全体,就可以看到OutOfMemeoryException了(如果你没有观望是坏,可能是你的机械太强大了,请换一个又甚的文本)。在调试器里面实践后出现异常后,加载进SOS进行解析:

https://stackoverflow.com/questions/24666604/what-would-cause-so-many-unstarted-threads

 

https://www.researchgate.net/publication/228977836_Optimizing_concurrency_levels_in_the_net_threadpool_A_case_study_of_controller_design_and_implementation

 (318.1688): CLR
exception – code e0434352 (first chance)

 

… …

Thread Pooling

#

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686756(v=vs.85).aspx

#
OutOfMemeoryException已经废弃来了

Thread Pools

#

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686760%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

 (318.1688): CLR
exception – code e0434352 (!!! second chance !!!)

 

eax=0017eb74
ebx=00000005 ecx=00000005 edx=00000000 esi=0017ec20 edi=005595e0

https://github.com/dotnet/coreclr/blob/master/Documentation/botr/threading.md

eip=753b9617
esp=0017eb74 ebp=0017ebc4 iopl=0         nv up ei pl nz ac pe nc

https://blogs.msdn.microsoft.com/ericeil/2009/04/23/clr-4-0-threadpool-improvements-part-1/

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    
        efl=00000216

http://joeduffyblog.com/2008/09/17/building-a-custom-thread-pool-series-part-3-incorporating-work-stealing-queues/

KERNELBASE!RaiseException+0x54:

http://www.cnblogs.com/Refresh-air/p/3312538.html

753b9617
c9              leave

https://msdn.microsoft.com/en-us/magazine/ff960958.aspx?f=255&MSPPError=-2147217396

0:000> .loadby sos
clr

https://msdn.microsoft.com/en-us/magazine/mt149362?author=erika+fuentes

0:000> !pe

Thread Management and other CLR TidBits

Exception object:
744a8e84

Programming the Thread Pool in the .NET Framework

Exception type:  
System.OutOfMemoryException

https://msdn.microsoft.com/en-us/library/ms973903.aspx

Message:         
<none>

 

InnerException:  
<none>

那些年,我们联合找的异步编程[系列]

StackTrace
(generated):

浅谈线程池(下):相关考试和注意事项

SP       IP      
Function

Optimize managed code for multi-core machines. MSDN Magazine, October
2007.

#

http://msdn.microsoft.com/en-us/magazine/ cc163340.aspx

# 不产生所预期,StreamReader里面使用StringBuilder将文件文件读入到一个字符串里。而StringBuilder是动态

 

# 分配内存的。

Parallel Programming with Microsoft .NET

#

https://msdn.microsoft.com/en-us/library/ff963553.aspx

    0017ED38
5713E61E mscorlib_ni!System.Text.StringBuilder.ToString()+0x1e

 

    0017ED64
57121991 mscorlib_ni!System.IO.StreamReader.ReadToEnd()+0x7d

Optimize Managed Code For Multi-Core
Machines

    0017ED78
002F0136
ConsoleApplication1!ConsoleApplication1.Program.Main(System.String[])+0xc6

Improve Scalability With New Thread Pool
APIs

 

 

StackTraceString:
<none>

http://www.albahari.com/threading/#_Thread_Pooling

HResult:
8007000e

 

#

https://blogs.msdn.microsoft.com/ericeil/2008/06/20/windows-io-threads-vs-managed-io-threads/

# 使用AnalyzeOOM来分析一下因,看看是GC哪一个内存区域导致了是很。

http://stackoverflow.com/questions/2099947/simple-description-of-worker-and-i-o-threads-in-net

#

https://blogs.msdn.microsoft.com/junfeng/2008/11/24/threadpool-unsafequeuenativeoverlapped/

0:000> !ao

https://blogs.msdn.microsoft.com/junfeng/2008/12/01/threadpool-bindhandle/

#

BindIoCompletionCallback function,

# 找到了,是颇目标堆(Large Object Heap –
LOH),GC在尝申请一个1.5G之内存空间时

On completion of an I/O request involving this file, a non-I/O worker
thread will execute the specified callback function.

# 遭拒。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa363484(v=vs.85).aspx

#

http://stackoverflow.com/questions/137400/whats-the-difference-between-a-worker-thread-and-an-i-o-thread

Managed OOM
occured after GC #312 (Requested to allocate 1649667816 bytes)

I/O Completion Ports

Reason:
Didn’t have enough memory to allocate an LOH segment

https://msdn.microsoft.com/en-us/library/aa365198%28VS.85%29.aspx?f=255&MSPPError=-2147217396

Detail: LOH:
Failed to reserve memory (1652555776 bytes)

https://blogs.msdn.microsoft.com/junfeng/2008/07/21/managed-threadpool-vs-win32-threadpool-pre-vista/

#

Concurrency – Throttling Concurrency in the CLR 4.0 ThreadPool

# 使用!eeheap
–gc命令找到GC里,各个generation的积的序曲地址与竣工地址

https://msdn.microsoft.com/en-us/magazine/ff960958.aspx

#

http://www.danielmoth.com/Blog/New-And-Improved-CLR-4-Thread-Pool-Engine.aspx 

0:000> !eeheap -gc

UnsafeQueueUserWorkItem and what exactly does “does not propagate the
calling stack”
mean?

Number of GC
Heaps: 1

Asynchronous operations, pinning

generation 0
starts at 0x744a8e78

 

generation 1
starts at 0x7446a408

win32threadpool

generation 2
starts at 0x01911000

DWORD __stdcall ThreadpoolMgr::WorkerThreadStart(LPVOID lpArgs)

ephemeral segment
allocation context: none

 

 segment     begin
allocated size

500 Id: 25bf4.1b858 Suspend: 0 Teb: 00007ff6`3f28a000 Unfrozen
Child-SP RetAddr Call Site
00000020`a84cf558 00007fff`d4ea1118 ntdll!NtWaitForSingleObject+0xa
00000020`a84cf560 00007fff`ce50ce66
KERNELBASE!WaitForSingleObjectEx+0x94
00000020`a84cf600 00007fff`ce50d247 clr!CLRSemaphore::Wait+0x8a
00000020`a84cf6c0 00007fff`ce50d330
clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109
00000020`a84cf700 00007fff`ce5de8b6
clr!ThreadpoolMgr::WorkerThreadStart+0x1b9
00000020`a84cf7a0 00007fff`d60613d2
clr!Thread::intermediateThreadProc+0x7d
00000020`a84cfb60 00007fff`d7be5454
kernel32!BaseThreadInitThunk+0x22
00000020`a84cfb90 00000000`00000000 ntdll!RtlUserThreadStart+0x34

01910000 01911000 0290aee0 0xff9ee0(16752352)

501 Id: 25bf4.368 Suspend: 0 Teb: 00007ff6`3f288000 Unfrozen
Child-SP RetAddr Call Site
00000020`a854f448 00007fff`d4ea1118 ntdll!NtWaitForSingleObject+0xa
00000020`a854f450 00007fff`ce50ce66
KERNELBASE!WaitForSingleObjectEx+0x94
00000020`a854f4f0 00007fff`ce50d247 clr!CLRSemaphore::Wait+0x8a
00000020`a854f5b0 00007fff`ce50d330
clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109
00000020`a854f5f0 00007fff`ce5de8b6
clr!ThreadpoolMgr::WorkerThreadStart+0x1b9
00000020`a854f690 00007fff`d60613d2
clr!Thread::intermediateThreadProc+0x7d
00000020`a854fcd0 00007fff`d7be5454
kernel32!BaseThreadInitThunk+0x22
00000020`a854fd00 00000000`00000000 ntdll!RtlUserThreadStart+0x34

03fd0000 03fd1000 04fcd3ec 0xffc3ec(16761836)

502 Id: 25bf4.3d690 Suspend: 0 Teb: 00007ff6`3f286000 Unfrozen
Child-SP RetAddr Call Site
00000020`a85cfa98 00007fff`d4ea1118 ntdll!NtWaitForSingleObject+0xa
00000020`a85cfaa0 00007fff`ce50ce66
KERNELBASE!WaitForSingleObjectEx+0x94
00000020`a85cfb40 00007fff`ce50d247 clr!CLRSemaphore::Wait+0x8a
00000020`a85cfc00 00007fff`ce50d330
clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109
00000020`a85cfc40 00007fff`ce5de8b6
clr!ThreadpoolMgr::WorkerThreadStart+0x1b9
00000020`a85cfce0 00007fff`d60613d2
clr!Thread::intermediateThreadProc+0x7d
00000020`a85cff20 00007fff`d7be5454
kernel32!BaseThreadInitThunk+0x22
00000020`a85cff50 00000000`00000000 ntdll!RtlUserThreadStart+0x34

… …

503 Id: 25bf4.406c Suspend: 0 Teb: 00007ff6`3f284000 Unfrozen
Child-SP RetAddr Call Site
00000020`a864fc58 00007fff`d4ea1118 ntdll!NtWaitForSingleObject+0xa
00000020`a864fc60 00007fff`ce50ce66
KERNELBASE!WaitForSingleObjectEx+0x94
00000020`a864fd00 00007fff`ce50d247 clr!CLRSemaphore::Wait+0x8a
00000020`a864fdc0 00007fff`ce50d330
clr!ThreadpoolMgr::UnfairSemaphore::Wait+0x109
00000020`a864fe00 00007fff`ce5de8b6
clr!ThreadpoolMgr::WorkerThreadStart+0x1b9
00000020`a864fea0 00007fff`d60613d2
clr!Thread::intermediateThreadProc+0x7d
00000020`a864fee0 00007fff`d7be5454
kernel32!BaseThreadInitThunk+0x22
00000020`a864ff10 00000000`00000000 ntdll!RtlUserThreadStart+0x34

73ca0000 73ca1000 744aae84 0x809e84(8429188)

 

Large object heap
starts at 0x02911000

================

#

OS Thread Id: 0x8e54 (4)
Current frame: (MethodDesc
000007fe91923930 +0x48
ConsoleApplication5.Program.ThreadProc(System.Object))
Child-SP         RetAddr          Caller,
Callee
000000001bdbeda0 000007fee76fd0b5
(MethodDesc 000007fee72807d0 +0x285
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bdbee00 000007fef12709d1
clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x29, calling
clr!ThreadpoolMgr::EnsureGateThreadRunning
000000001bdbef00 000007fee76fce19
(MethodDesc 000007fee72807c0 +0x9
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean)), calling
(MethodDesc 000007fee72807d0 +0
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bdbef30 000007fee764270f
(MethodDesc 000007fee7272008 +0x6f
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()),
calling (MethodDesc 000007fee72807c0 +0
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bdbef80 000007fee763764a
(MethodDesc 000007fee7271d60 +0x1ea
System.Threading.ThreadPoolWorkQueue.Dispatch()), calling
000007fe919d0060
000000001bdbf040 000007fef1119e03
clr!CallDescrWorkerInternal+0x83
000000001bdbf080 000007fef1119e7e
clr!CallDescrWorkerWithHandler+0x4a, calling
clr!CallDescrWorkerInternal
000000001bdbf0a0 000007fef1111feb
clr!HardCodedMetaSig::GetBinarySig+0x58, calling
clr!_security_check_cookie
000000001bdbf0c0 000007fef1119ef0
clr!MethodDescCallSite::CallTargetWorker+0x2e2, calling
clr!CallDescrWorkerWithHandler
000000001bdbf100 000007fef10c6472
clr!ArgIteratorTemplate<ArgIteratorBase>::ComputeReturnFlags+0x4a,
calling clr!SigPointer::PeekElemTypeClosed
000000001bdbf130 000000007714dba8
ntdll!RtlAllocateHeap+0x178, calling
ntdll!TpAlpcRegisterCompletionList+0xa720
000000001bdbf150 000007fef111b34a
clr!MethodDescCallSite::CallTargetWorker+0xa1, calling
clr!_chkstk
000000001bdbf1a0 000007fef111b281
clr!ArgIteratorTemplate<ArgIteratorBase>::ForceSigWalk+0x139,
calling clr!ArgIteratorBase::IsVarArg
000000001bdbf270 000007fef1270bf9
clr!QueueUserWorkItemManagedCallback+0x2a, calling
clr!MethodDescCallSite::CallTargetWorker
000000001bdbf350 000007fef112458c
clr!Frame::Pop+0x50
000000001bdbf390 000007fef112451a
clr!COMCustomAttribute::PopSecurityContextFrame+0x192, calling
clr!Frame::Pop+0x24
000000001bdbf420 000007fef10b31ec
clr!ClrFlsIncrementValue+0x18, calling clr!ClrFlsGetBlock
000000001bdbf430 000007fef1124413
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame+0x18,
calling clr!Frame::Push
000000001bdbf460 000007fef11243f3
clr!FrameWithCookie<DebuggerU2MCatchHandlerFrame>::FrameWithCookie<DebuggerU2MCatchHandlerFrame>+0x1c,
calling
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame
000000001bdbf480 0000000077152631
ntdll!LdrGetProcedureAddress+0x11, calling
ntdll!LdrGetProcedureAddressEx
000000001bdbf490 000007fef1124491
clr!COMCustomAttribute::PopSecurityContextFrame+0xbd, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x12c
000000001bdbf4a0 000007fef1123ec1
clr!CORProfilerTrackThreads+0x9, calling clr!CORProfilerPresent
000000001bdbf4d0 000007fef126fcf6
clr!Thread::HasStarted+0x16e, calling
clr!CORProfilerTrackThreads
000000001bdbf520 000007fef11245ef
clr!Thread::SetExposedContext+0x93, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x48
000000001bdbf580 000007fef1270b60
clr!ManagedPerAppDomainTPCount::DispatchWorkItem+0xb4, calling
clr!Thread::SetExposedContext+0x64
000000001bdbf680 000007fefe860c82
ole32!CoUninitialize+0xbe
[d:\w7rtm\com\ole32\com\class\compobj.cxx:2657], calling
ole32!NotifyInitializeSpies
[d:\w7rtm\com\ole32\com\class\compobj.cxx:1717]
000000001bdbf6b0 000007fef126fec9
clr!Thread::SetApartment+0xf9, calling clr!Thread::GetApartment
000000001bdbf6d0 000007fef1299297
clr!PerAppDomainTPCountList::GetAppDomainIndexForThreadpoolDispatch+0x6f
000000001bdbf710 000007fef129920b
clr!ThreadpoolMgr::ExecuteWorkRequest+0x4c
000000001bdbf740 000007fef129910a
clr!ThreadpoolMgr::WorkerThreadStart+0xf6, calling
clr!ThreadpoolMgr::ExecuteWorkRequest
000000001bdbf770 0000000076f01a0a
kernel32!HeapFree+0xa, calling ntdll!RtlFreeHeap
000000001bdbf7a0 000007fef10b435d
clr!EEHeapFreeInProcessHeap+0x39, calling kernel32!HeapFree
000000001bdbf800 000007fef11833de
clr!Thread::intermediateThreadProc+0x7d
000000001bdbf900 000007fef11833c7
clr!Thread::intermediateThreadProc+0x66, calling clr!_chkstk
000000001bdbf940 0000000076ef59bd
kernel32!BaseThreadInitThunk+0xd
000000001bdbf970 000000007712a2e1
ntdll!RtlUserThreadStart+0x21
OS Thread Id: 0x7328 (5)
Current frame:
ntdll!NtDelayExecution+0xa
Child-SP         RetAddr          Caller,
Callee
000000001c1fec70 000007fefd051203
KERNELBASE!SleepEx+0xb3, calling ntdll!NtDelayExecution
000000001c1fece0 000007fefd05394b
KERNELBASE!SetThreadLocale+0xab, calling
ntdll!RtlActivateActivationContextUnsafeFast
000000001c1fed10 000007fef12b69f8
clr!CExecutionEngine::ClrSleepEx+0x29, calling kernel32!SleepEx
000000001c1fed40 000007fef12b6b81
clr!Thread::UserSleep+0x76, calling clr!ClrSleepEx
000000001c1fed60 000007fef10b49d4
clr!HelperMethodFrame::Push+0x19, calling clr!GetThread
000000001c1fed80 000007fee763bd33
(MethodDesc 000007fee7271990 +0x53
System.IO.__ConsoleStream.Write(Byte[], Int32, Int32)), calling
(MethodDesc 000007fee7396dd8 +0
System.IO.__ConsoleStream.WriteFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle,
Byte[], Int32, Int32, Boolean))
000000001c1fed90 000007fef12b6aa8
clr!ThreadNative::Sleep+0x98, calling clr!Thread::UserSleep
000000001c1fedd0 000007fee763ac59
(MethodDesc 000007fee727e7d8 +0xe9 System.IO.StreamWriter.Flush(Boolean,
Boolean))
000000001c1fedf0 000007fee763bc23
(MethodDesc 000007fee7396d98 +0x23
System.IO.__ConsoleStream.Flush())
000000001c1fee30 000007fee763bacc
(MethodDesc 000007fee71a1c58 +0xcc
System.IO.TextWriter.WriteLine(System.String))
000000001c1fee90 000007fee763bccb
(MethodDesc 000007fee7396f48 +0x4b
System.IO.TextWriter+SyncTextWriter.WriteLine(System.String)), calling
clr!JIT_MonExitWorker_InlineGetThread
000000001c1feea0 000007fee763be3e
(MethodDesc 000007fee71a12d8 +0x2e
System.Console.WriteLine(System.String)), calling (MethodDesc
000007fee71a14a8 +0
System.Console.InitializeStdOutError(Boolean))
000000001c1feec8 000007fef12b6a6b
clr!ThreadNative::Sleep+0x5b, calling
clr!LazyMachStateCaptureState
000000001c1feee0 000007fe91a4026c
(MethodDesc 000007fe91923940 +0x3c
ConsoleApplication5.Program.ThreadProc2(System.Object)), calling
(MethodDesc 000007fee719f428 +0
System.Threading.Thread.Sleep(Int32))
000000001c1fef10 000007fee76fd0b5
(MethodDesc 000007fee72807d0 +0x285
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001c1fef70 000007fef12709d1
clr!ManagedPerAppDomainTPCount::SetAppDomainRequestsActive+0x29, calling
clr!ThreadpoolMgr::EnsureGateThreadRunning
000000001c1ff070 000007fee76fce19
(MethodDesc 000007fee72807c0 +0x9
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean)), calling
(MethodDesc 000007fee72807d0 +0
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001c1ff0a0 000007fee764270f
(MethodDesc 000007fee7272008 +0x6f
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()),
calling (MethodDesc 000007fee72807c0 +0
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001c1ff0f0 000007fee763764a
(MethodDesc 000007fee7271d60 +0x1ea
System.Threading.ThreadPoolWorkQueue.Dispatch()), calling
000007fe919d0060
000000001c1ff1b0 000007fef1119e03
clr!CallDescrWorkerInternal+0x83
000000001c1ff1f0 000007fef1119e7e
clr!CallDescrWorkerWithHandler+0x4a, calling
clr!CallDescrWorkerInternal
000000001c1ff210 000007fef1111feb
clr!HardCodedMetaSig::GetBinarySig+0x58, calling
clr!_security_check_cookie
000000001c1ff230 000007fef1119ef0
clr!MethodDescCallSite::CallTargetWorker+0x2e2, calling
clr!CallDescrWorkerWithHandler
000000001c1ff270 000007fef10c6472
clr!ArgIteratorTemplate<ArgIteratorBase>::ComputeReturnFlags+0x4a,
calling clr!SigPointer::PeekElemTypeClosed
000000001c1ff2c0 000007fef111b34a
clr!MethodDescCallSite::CallTargetWorker+0xa1, calling
clr!_chkstk
000000001c1ff310 000007fef111b281
clr!ArgIteratorTemplate<ArgIteratorBase>::ForceSigWalk+0x139,
calling clr!ArgIteratorBase::IsVarArg
000000001c1ff3e0 000007fef1270bf9
clr!QueueUserWorkItemManagedCallback+0x2a, calling
clr!MethodDescCallSite::CallTargetWorker
000000001c1ff400 000007fef1a5119a
mscoreei!DllMainCRTStartup+0xce, calling mscoreei!DllMain
000000001c1ff4b0 000007fef1182676
clr!REGUTIL::GetConfigInteger+0x62, calling
clr!REGUTIL::RegCacheValueNameSeenPerhaps
000000001c1ff4c0 000007fef112458c
clr!Frame::Pop+0x50
000000001c1ff500 000007fef112451a
clr!COMCustomAttribute::PopSecurityContextFrame+0x192, calling
clr!Frame::Pop+0x24
000000001c1ff510 000007fefd06aa36
KERNELBASE!SetThreadStackGuarantee+0x46, calling
KERNELBASE!GetSystemInfo
000000001c1ff530 000007fef10b31ec
clr!ClrFlsIncrementValue+0x18, calling clr!ClrFlsGetBlock
000000001c1ff590 000007fef10b31ec
clr!ClrFlsIncrementValue+0x18, calling clr!ClrFlsGetBlock
000000001c1ff5a0 000007fef1124413
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame+0x18,
calling clr!Frame::Push
000000001c1ff5c0 000007fef10c3a6c
clr!ThreadStore::CheckForEEShutdown+0x1e, calling
clr!ThreadStore::OtherThreadsComplete
000000001c1ff5d0 000007fef11243f3
clr!FrameWithCookie<DebuggerU2MCatchHandlerFrame>::FrameWithCookie<DebuggerU2MCatchHandlerFrame>+0x1c,
calling
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame
000000001c1ff5f0 000007fef126fdb2
clr!ThreadStore::TransferStartedThread+0x83, calling
clr!ThreadStore::CheckForEEShutdown
000000001c1ff600 000007fef1124491
clr!COMCustomAttribute::PopSecurityContextFrame+0xbd, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x12c
000000001c1ff610 000007fef1123ec1
clr!CORProfilerTrackThreads+0x9, calling clr!CORProfilerPresent
000000001c1ff640 000007fef126fcf6
clr!Thread::HasStarted+0x16e, calling
clr!CORProfilerTrackThreads
000000001c1ff690 000007fef11245ef
clr!Thread::SetExposedContext+0x93, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x48
000000001c1ff6f0 000007fef1270b60
clr!ManagedPerAppDomainTPCount::DispatchWorkItem+0xb4, calling
clr!Thread::SetExposedContext+0x64
000000001c1ff700 000007fef1149f94
clr!SafeReleasePreemp+0x74
000000001c1ff740 000007fefe8622bd
ole32!IsRunningInRPCSS+0x41
[d:\w7rtm\com\ole32\com\class\compobj.cxx:1959], calling
ole32!__security_check_cookie
[d:\win7sp1_ldr\minkernel\crts\crtw32\misc\amd64\amdsecgs.asm:72]
000000001c1ff780 000007fefe862528
ole32!RegisterThreadCleanupCallback+0x28
[d:\w7rtm\com\ole32\com\class\compobj.cxx:1855], calling
KERNELBASE!FlsSetValue
000000001c1ff7f0 000007fefe860c82
ole32!CoUninitialize+0xbe
[d:\w7rtm\com\ole32\com\class\compobj.cxx:2657], calling
ole32!NotifyInitializeSpies
[d:\w7rtm\com\ole32\com\class\compobj.cxx:1717]
000000001c1ff820 000007fef126fec9
clr!Thread::SetApartment+0xf9, calling clr!Thread::GetApartment
000000001c1ff840 000007fef1299297
clr!PerAppDomainTPCountList::GetAppDomainIndexForThreadpoolDispatch+0x6f
000000001c1ff880 000007fef129920b
clr!ThreadpoolMgr::ExecuteWorkRequest+0x4c
000000001c1ff8b0 000007fef129910a
clr!ThreadpoolMgr::WorkerThreadStart+0xf6, calling
clr!ThreadpoolMgr::ExecuteWorkRequest
000000001c1ff8e0 0000000076f01a0a
kernel32!HeapFree+0xa, calling ntdll!RtlFreeHeap
000000001c1ff910 000007fef10b435d
clr!EEHeapFreeInProcessHeap+0x39, calling kernel32!HeapFree
000000001c1ff970 000007fef11833de
clr!Thread::intermediateThreadProc+0x7d
000000001c1ffaf0 000007fef11833c7
clr!Thread::intermediateThreadProc+0x66, calling clr!_chkstk
000000001c1ffb30 0000000076ef59bd
kernel32!BaseThreadInitThunk+0xd
000000001c1ffb60 000000007712a2e1
ntdll!RtlUserThreadStart+0x21

#
LOH的胚胎地址找到了,0x02911000便是LOH的原初地址

 

# 已经分配了0x02913240单字节,所以结束地址便是

OS Thread Id: 0x3608 (4)
Current frame: (MethodDesc
000007fe91923920 +0x49 ConsoleApplication5.Program.DoWork())
Child-SP         RetAddr          Caller,
Callee
000000001bfef060 000007feda63d0b5
(MethodDesc 000007feda1c07d0 +0x285
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bfef1c0 000007feda63ce19
(MethodDesc 000007feda1c07c0 +0x9
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean)), calling
(MethodDesc 000007feda1c07d0 +0
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bfef1f0 000007feda63cdd7
(MethodDesc 000007feda1c07b0 +0x57
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object)), calling (MethodDesc
000007feda1c07c0 +0
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object, Boolean))
000000001bfef240 000007feda5b0301
(MethodDesc 000007feda1cc3f0 +0x51
System.Threading.ThreadHelper.ThreadStart()), calling (MethodDesc
000007feda1c07b0 +0
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,
System.Threading.ContextCallback, System.Object))
000000001bfef290 000007fef1119e03
clr!CallDescrWorkerInternal+0x83
000000001bfef2d0 000007fef1119e7e
clr!CallDescrWorkerWithHandler+0x4a, calling
clr!CallDescrWorkerInternal
000000001bfef310 000007fef1119ef0
clr!MethodDescCallSite::CallTargetWorker+0x2e2, calling
clr!CallDescrWorkerWithHandler
000000001bfef350 000007fef10c6472
clr!ArgIteratorTemplate<ArgIteratorBase>::ComputeReturnFlags+0x4a,
calling clr!SigPointer::PeekElemTypeClosed
000000001bfef3a0 000007fef111b34a
clr!MethodDescCallSite::CallTargetWorker+0xa1, calling
clr!_chkstk
000000001bfef3f0 000007fef111b281
clr!ArgIteratorTemplate<ArgIteratorBase>::ForceSigWalk+0x139,
calling clr!ArgIteratorBase::IsVarArg
000000001bfef4c0 000007fef123594d
clr!ThreadNative::KickOffThread_Worker+0x105, calling
clr!MethodDescCallSite::CallTargetWorker
000000001bfef520 000000007712a3e2
ntdll!RtlUserThreadStart+0x122, calling
ntdll!RtlLeaveCriticalSection
000000001bfef590 000000007714dba8
ntdll!RtlAllocateHeap+0x178, calling
ntdll!TpAlpcRegisterCompletionList+0xa720
000000001bfef650 000007fefe862645
ole32!InitThreadCtx+0x41
[d:\w7rtm\com\ole32\com\class\compobj.cxx:2288]
000000001bfef670 000007fefe8629bf
ole32!TLSAddToMap+0x9f
[d:\w7rtm\com\ole32\com\class\tls.cxx:166], calling
ntdll!RtlLeaveCriticalSection
000000001bfef680 000007fefe8625b5
ole32!wCoInitializeEx+0x79
[d:\w7rtm\com\ole32\com\class\compobj.cxx:2467], calling
ole32!InitThreadCtx
[d:\w7rtm\com\ole32\com\class\compobj.cxx:2235]
000000001bfef6a0 000007fefe862528
ole32!RegisterThreadCleanupCallback+0x28
[d:\w7rtm\com\ole32\com\class\compobj.cxx:1855], calling
KERNELBASE!FlsSetValue
000000001bfef6d0 000007fef11245bb
clr!ManagedThreadCallState::IsAppDomainEqual+0x1f, calling
clr!ADID::operator==
000000001bfef700 000007fef112458c
clr!Frame::Pop+0x50
000000001bfef730 000007fef10b378a
clr!EEHeapAllocInProcessHeap+0x46, calling
ntdll!RtlAllocateHeap
000000001bfef740 000007fef112451a
clr!COMCustomAttribute::PopSecurityContextFrame+0x192, calling
clr!Frame::Pop+0x24
000000001bfef760 000007fef126f57a
clr!Thread::AllocateIOCompletionContext+0x13, calling clr!operator
new
000000001bfef770 000007fef10b31ec
clr!ClrFlsIncrementValue+0x18, calling clr!ClrFlsGetBlock
000000001bfef7d0 000007fef126fdb2
clr!ThreadStore::TransferStartedThread+0x83, calling
clr!ThreadStore::CheckForEEShutdown
000000001bfef7e0 000007fef1124413
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame+0x18,
calling clr!Frame::Push
000000001bfef810 000007fef11243f3
clr!FrameWithCookie<DebuggerU2MCatchHandlerFrame>::FrameWithCookie<DebuggerU2MCatchHandlerFrame>+0x1c,
calling
clr!DebuggerU2MCatchHandlerFrame::DebuggerU2MCatchHandlerFrame
000000001bfef820 000007fef126fcf6
clr!Thread::HasStarted+0x16e, calling
clr!CORProfilerTrackThreads
000000001bfef840 000007fef1124491
clr!COMCustomAttribute::PopSecurityContextFrame+0xbd, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x12c
000000001bfef8d0 000007fef11245ef
clr!Thread::SetExposedContext+0x93, calling
clr!COMCustomAttribute::PopSecurityContextFrame+0x48
000000001bfef930 000007fef1235831
clr!ThreadNative::KickOffThread+0xbd, calling
clr!Thread::SetExposedContext+0x64
000000001bfef970 0000000076f01a0a
kernel32!HeapFree+0xa, calling ntdll!RtlFreeHeap
000000001bfef9d0 000007fef10b4384
clr!operator delete+0x14, calling clr!EEHeapFreeInProcessHeap
000000001bfefa00 000007fef11833de
clr!Thread::intermediateThreadProc+0x7d
000000001bfefb00 000007fef11833c7
clr!Thread::intermediateThreadProc+0x66, calling clr!_chkstk
000000001bfefb40 0000000076ef59bd
kernel32!BaseThreadInitThunk+0xd
000000001bfefb70 000000007712a2e1
ntdll!RtlUserThreadStart+0x21

# 0x02911000 +
0x02913240

#

 segment     begin
allocated size

02910000 02911000 02913240 0x2240(8768)

Total
Size:              Size: 0x629424c0 (1653875904) bytes.


GC Heap
Size:            Size: 0x629424c0 (1653875904) bytes.

#

# 使用dumpheap看一下LOH当中各个对象的内存分配情况。

#

#
dumpheap的参数中,0x02911000是若翻看的内存的苗子地址,

# 而0x02911000 +
0x02913240凡查的了地址

#

0:000> !dumpheap -stat
02911000 02911000+02913240

total 0
objects

Statistics:

      MT   
Count    TotalSize Class Name

00529748       
4           84      Free

57166c28       
3         8720 System.Object[]

#

# 不发所预期,StringBuilder和Char[]目标极其多,但是

#
Char[]的数组大小来171M的多。

#

571afb78    
1119        31332 System.Text.StringBuilder

571b1d88     1120     17933440
System.Char[]

Total 2246
objects

#

# 使用!dumpheap的-mt参数看看char[]勤组的详实内存分配情况

#

#
571b1d88斯参数,来自于前的!dumpheap命令的出口(注意高亮显示的地方)

# 这个参数告诉dumpheap命令,只检索char[]数组(Method
table是571b1d88)

# 的情况。

#

0:000> !dumpheap -mt 571b1d88 02911000
02911000+02913240

 Address      
MT     Size

03fd1000 571b1d88    16012    

… …

05222c90
571b1d88    16012    

total 0
objects

Statistics:

      MT   
Count    TotalSize Class Name

571b1d88    
1120     17933440 System.Char[]

Total 1120
objects

#

# 随便选一个对象(注意点一个高亮显示的文本),看看她到底给谁引用了,

# 导致GC一直无放它,毕竟自己电脑的来2G的情理内存,读取几百兆之文件,

# 就接触了OutOfMemoryException,的确有些离谱。

#

0:000> !gcroot 03fd1000

Note: Roots found
on stacks may be false positives. Run “!help gcroot” for

more info.

Scan Thread 0
OSTHread 1688

ESP:17eca4:Root: 0191d2e0(System.Text.StringBuilder)->

 744a4fd0(System.Text.StringBuilder)->

 … …

 5de44814(System.Text.StringBuilder)->

Command cancelled
at the user’s request.

 03fd1000(System.Char[])

#

# 再看看0x0191d2e0这个StringBuilder对象还在哪些地方被引用到了,

# 根据GC的贯彻,堆栈上挨家挨户函数的一对变量是当作root来拍卖的

#

0:000> !gcroot 0191d2e0

Note: Roots found
on stacks may be false positives. Run “!help gcroot” for

more info.

Scan Thread 0
OSTHread 1688

ESP:17eca4:Root: 0191d2e0(System.Text.StringBuilder)

ESP:17eca8:Root: 0191d2e0(System.Text.StringBuilder)

ESP:17ecb4:Root: 0191d2e0(System.Text.StringBuilder)

ESP:17ecbc:Root: 0191d2e0(System.Text.StringBuilder)

ESP:17ed3c:Root: 0191d2e0(System.Text.StringBuilder)

ESP:17ed58:Root: 0191d2e0(System.Text.StringBuilder)

Scan Thread 2
OSTHread ce8

#

# 从前面的输出,随便找点儿个目标(前面标注的公文),看看它还是何等函数的有变量

# 例如17ed58斯地点在System.IO.StreamReader.ReadToEnd()和

#
System.Text.StringBuilder.ToString()之间,也就是StreamReader.ReadToEnd()

# 这个函数定义的,至此,基本上我们可以看就找到影响属性的首恶了。

#

0:000> !dumpstack

OS Thread Id:
0x1688 (0)

Current frame:
KERNELBASE!RaiseException+0x54

ChildEBP
RetAddr Caller, Callee

0017eb7c 753b9617
KERNELBASE!RaiseException+0x54, calling ntdll!RtlRaiseException

0017eba0 5888bc5e
clr!DllUnregisterServerInternal+0x15c62, calling
clr!DllUnregisterServerInternal+0xa55b

0017ebac 588fa99c
clr!LogHelp_TerminateOnAssert+0x2df44, calling
clr!DllUnregisterServerInternal+0x15c45

0017ebbc 58871bd0
clr+0x1bd0, calling clr+0x1b8b

0017ebc4 588fac08
clr!LogHelp_TerminateOnAssert+0x2e1b0, calling
KERNEL32!RaiseException

0017ec54 5896ab0b
clr!CopyPDBs+0x4abd, calling
clr!LogHelp_TerminateOnAssert+0x2e03e

0017ec90 58b27c9e
clr!CorLaunchApplication+0x11756, calling clr!CopyPDBs+0x4a78

0017ecdc 588908f6
clr!CoUninitializeEE+0x272e, calling
clr!GetMetaDataInternalInterface+0xde18

0017ed30
5713e61e (MethodDesc 56f0c09c +0x1e
System.Text.StringBuilder.ToString()), calling 00242350

0017ed5c
57121991 (MethodDesc 56efff40 +0x7d
System.IO.StreamReader.ReadToEnd())

0017ed70 002f0136
(MethodDesc 00253840 +0xc6
ConsoleApplication1.Program.Main(System.String[]))

0017edd4 588721db
clr+0x21db

0017ede4 58894a2a
clr!CoUninitializeEE+0x6862, calling clr+0x21a8

… …

0017f91c 589daf00
clr!CorExeMain+0x1c, calling clr!GetCLRFunction+0xd6a

0017f954 718455ab
mscoreei!CorExeMain+0x38

0017f960 6f667f16
MSCOREE!CreateConfigStream+0x13f

0017f970 6f664de3
MSCOREE!CorExeMain+0x8, calling MSCOREE!CorExeMain+0x2f14

0017f978 75d41194
KERNEL32!BaseThreadInitThunk+0x12

0017f984 7723b495
ntdll!RtlInitializeExceptionChain+0x63

0017f9c4
7723b468 ntdll!RtlInitializeExceptionChain+0x36, calling
ntdll!RtlInitializeExceptionChain+0x3c