知识大全 Out Of Memory的分析及诊断方法

Posted 命令

篇首语:学习并不等于就是摹仿某些东西,而是掌握技巧和方法。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Out Of Memory的分析及诊断方法相关的知识,希望对你有一定的参考价值。

Out Of Memory的分析及诊断方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  首先 什么是Out Of Memory?就是内存溢出 简称OOM(下边我就用这个简称了啊!) 说白了 就是程序想用内存的时候 OS没有那么多内存可以分配了 然后就抱OOM错误了

  首先介绍一下我这个项目的情况 基于exchange +sp +hmc+web service call 通过一个winform的模拟测试程序 单线程添加信息 循环 万次 每循环一次创建一个公司 开通邮件域名 并创建 个帐号 每个帐号都开通邮件服务 现在循环到 次左右的时候 w wp exe的内存占用为private bytes M virtual bytes M 听兄弟讲 他们做过类似的测试 当循环到 个的时候 会出现OOM的问题

  既然是OOM 我们当然要介绍一个超级cool的工具 debugdiag!(这个工具以后再介绍 因为要贴N多图 实在痛苦……)通过debugdiag抓memory leak的dump( M) 发现有如下问题 mscorwks泄漏了 M左右的内存

  现在转到windbg中来 我们首先看命令!eeheap 它一共有两个参数

   > !help eeheap

  

  !EEHeap [ gc] [ loader]

  首先看一下 gc的参数 !eeheap gc 这个命令表明 我们程序占用托管堆的大小

   > !eeheap gc

  Number of GC Heaps

  generation starts at x ff f

  generation starts at x f df c

  generation starts at x c

  ephemeral segment allocation context ( x bcbf x bd c)

  segment begin allocated size

   ead a c c a d x edc( )

   e a d a f b x f b ( )

   c c bd c x fc c( )

  Large object heap starts at x c

  segment begin allocated size

   c c cfbbd x abd ( )

  Total Size xa d ( )

  

  GC Heap Size xa d ( )

  dump大小为 M 托管堆大小为 M不到 差别很大的!剩下的内存在哪里?现在来看一个新的命令 !address 运行后 会有一坨又一坨的输出 我们关心的是后面的summary 如下

   Usage SUMMARY

  TotSize ( KB) Pct(Tots) Pct(Busy) Usage

   b ( ) % % RegionUsageIsVAD

   c b ( ) % % RegionUsageFree

   d ( ) % % RegionUsageImage

   fc ( ) % % RegionUsageStack

   ( ) % % RegionUsageTeb

   ( ) % % RegionUsageHeap

   ( ) % % RegionUsagePageHeap

   ( ) % % RegionUsagePeb

   ( ) % % RegionUsageProcessParametrs

   ( ) % % RegionUsageEnvironmentBlock

  Tot fff ( KB) Busy b c ( KB)

   Type SUMMARY

  TotSize ( KB) Pct(Tots) Usage

   c b ( ) % <free>

   c ( ) % MEM_IMAGE

   a ( ) % MEM_MAPPED

  a d ( ) % MEM_PRIVATE

   State SUMMARY

  TotSize ( KB) Pct(Tots) Usage

  ee ( ) % MEM_MIT

   c b ( ) % MEM_FREE

   ca ( ) % MEM_RESERVE

  上面的信息比较有意思 RegionUsageImage代表的是dlls占用的内存 一共是 M RegionUsageheap 代表的是NT heaps 一共是 M MEM_MIT和MEM_RESERVE加起来 是virtual memory 他俩的合计是 M 我们还少看了什么?!eeheap还有一个参数 是 loader 运行一下后 会有N长的结果 我们看一部分

  !eeheap –loader

  Domain fbd

  LowFrequencyHeap ba ( ) d ( ) ee ( ) b ( ) ea ( ) f ( f ) ( ) 很黄很暴力…… edc ( ) ee ( ) Size x ce ( )bytes

  Wasted x ( )bytes

  HighFrequencyHeap ba ( ) e ( f ) aa ( ) c ( f ) ( ) ( ) d ( ) 很黄很暴力 eba ( ) ee ( ) Size x a ( )bytes

  Wasted x ( )bytes

  StubHeap baa ( ) Size x ( )bytes

  Virtual Call Stub Heap

  IndcellHeap Size x ( )bytes

  LookupHeap Size x ( )bytes

  ResolveHeap Size x ( )bytes

  DispatchHeap Size x ( )bytes

  CacheEntryHeap bc ( ) Size x ( )bytes

  Total size x c ( )bytes

  一共占用了 M内存 继续看下面的内容 我居然发现了 个module!!!

  Module Thunk heaps

  Module aa Size x ( )bytes

  Module e Size x ( )bytes

  Module a Size x ( )bytes

  Module Size x ( )bytes

  =============很黄很暴力======================

  Module ee Size x ( )bytes

  Module ee Size x ( )bytes

  Module ee c Size x ( )bytes

  Module ee c Size x ( )bytes

  Total size x ( )bytes

  

  Total LoaderHeap size x a f ( )bytes

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

  问题基本出来了 居然在内存里面有将近 万个module!随便dump出来一个 看看 这里又有一个命令 !dumpmodule

  随便dump出来一个看 类似如下信息

   > !dumpmodule ee

  Name qrt x cw Version= Culture=neutral PublicKeyToken=null

  Attributes PEFile

  Assembly cf e

  LoaderHeap

  TypeDefToMethodTableMap edcc

  TypeRefToMethodTableMap edcc c

  MethodDefToDescMap edcc c

  FieldDefToDescMap edcc

  MemberRefToDescMap edcc c

  FileReferencesMap edcc

  AssemblyReferencesMap edcc

  MetaData start address ed ( bytes)

  这里可能看不到啥 那么我们加一个参数 mt来看看

   > !dumpmodule mt ee

  Name qrt x cw Version= Culture=neutral PublicKeyToken=null

  Attributes PEFile

  Assembly cf e

  LoaderHeap

  TypeDefToMethodTableMap edcc

  TypeRefToMethodTableMap edcc c

  MethodDefToDescMap edcc c

  FieldDefToDescMap edcc

  MemberRefToDescMap edcc c

  FileReferencesMap edcc

  AssemblyReferencesMap edcc

  MetaData start address ed ( bytes)

  Types defined in this module

  MT TypeDef Name

  

   ee c x Microsoft Xml Serialization GeneratedAssembly XmlSerializationReaderCreateUserResponseData

   ee c x Microsoft Xml Serialization GeneratedAssembly XmlSerializerContract

  Types referenced in this module

  MT TypeRef Name

  

   e eac x System Xml Serialization XmlSerializationReader

   e b x System Xml Serialization XmlSerializerImplementation

   e b c x Microsoft Provisioning WebServices HostedActiveDirectory CreateUserResponseData

   e be x System Xml XmlReader

   fd cc x System Collections Hashtable

   f a x e System Object

   e c x System Xml XmlQualifiedName

   c x System Boolean

   e a b x System Xml XmlNameTable

  出现了System Xml Serialization 大家熟悉吗?我们转过头来看debugdiag分析的call stack

  Call stack sample

  Address x c

  Allocation Time since tracking started

  Allocation Size Bytes

  Function Source Destination

  mscorjit!norls_allocator nraAllocNewPage+

  mscorjit!norls_allocator nraAlloc+ mscorjit!norls_allocator nraAllocNewPage

  mscorjit!jitNativeCode+ mscorjit!norls_allocator nraAlloc

  mscorjit!CILJit pileMethod+ d mscorjit!jitNativeCode

   x E C E

  mscorjit!Compiler impExpandInline+ aa

  mscorjit!Compiler fgMorphTree+

  mscorjit!Compiler fgMorphStmts+ mscorjit!Compiler fgMorphTree

  mscorjit!Compiler fgMorphBlocks+ mscorjit!Compiler fgMorphStmts

  mscorjit!Compiler fgMorph+ mscorjit!Compiler fgMorphBlocks

  mscorjit!Compiler pCompile+ f mscorjit!Compiler fgMorph

  mscorjit!Compiler pCompile+ d mscorjit!Compiler pCompile

  mscorjit!jitNativeCode+b mscorjit!Compiler pCompile

  mscorjit!CILJit pileMethod+ d mscorjit!jitNativeCode

   x EED FF

  System Xml Serialization TempAssembly InvokeReader(System Xml Serialization XmlMapping System Xml XmlReader System Xml Serialization XmlDeserializationEvents System String)

  System Xml Serialization TempAssembly InvokeReader(System Xml Serialization XmlMapping System Xml XmlReader System Xml Serialization XmlDeserializationEvents System String)

  System Xml Serialization XmlSerializer Deserialize(System Xml XmlReader System String System Xml Serialization XmlDeserializationEvents) System Xml Serialization TempAssembly InvokeReader(System Xml Serialization XmlMapping System Xml XmlReader System Xml Serialization XmlDeserializationEvents System String)

  System Xml Serialization XmlSerializer Deserialize(System Xml XmlReader System String) System Xml Serialization XmlSerializer Deserialize(System Xml XmlReader System String System Xml Serialization XmlDeserializationEvents)

  System Xml Serialization XmlSerializer Deserialize(System IO Stream) System Xml Serialization XmlSerializer Deserialize(System Xml XmlReader System String)

  Microsoft Provisioning Sdk Xml Serialization ProvisioningObjectFactory Convert[[System __Canon mscorlib] [System __Canon mscorlib]](System __Canon) System Xml Serialization XmlSerializer Deserialize(System IO Stream)

  Microsoft Provisioning WebServices ServiceBase Submit[[System __Canon mscorlib] [System __Canon mscorlib]](System __Canon System String System String Boolean) Microsoft Provisioning Sdk Xml Serialization ProvisioningObjectFactory Convert[[System __Canon mscorlib] [System __Canon mscorlib]](System __Canon)

  Microsoft Provisioning WebServices HostedActiveDirectory Service CreateOrganization(Microsoft Provisioning WebServices HostedActiveDirectory CreateOrganizationRequest Boolean)

   x E BE B

   x A E E

  System Web Services Protocols LogicalMethodInfo Invoke(System Object System Object[])

  System Web Services Protocols WebServiceHandler Invoke() System Web Services Protocols LogicalMethodInfo Invoke(System Object System Object[])

   x F FC

  System Threading _TimerCallback TimerCallback_Context(System Object)

  System Threading ExecutionContext Run(System Threading ExecutionContext System Threading ContextCallback System Object)

  webengine!HashtableIUnknown AddCallback+a

  webengine!HttpCompletion ProcessRequestInManagedCode+ a

  webengine!HttpCompletion ProcessRequestInManagedCode+ a

  webengine!HttpCompletion ProcessCompletion+ e webengine!HttpCompletion ProcessRequestInManagedCode

  webengine!CorThreadPoolWorkitemCallback+

   x F

   x F BC

  kernel !BaseThreadStart+

  看到这里 基本差不多 偶认为是exchange 内部的代码问题 此话怎讲?从头说 在System Xml Serialization下面 有一个by design的 bug 我们用reflector看XmlSerializer的构造代码

   this tempAssembly = cache[defaultNamespace type]

   if (this tempAssembly == null)

  

   lock (cache)

  

   this tempAssembly = cache[defaultNamespace type]

   if (this tempAssembly == null)

  

   XmlSerializerImplementation implementation

   Assembly assembly = TempAssembly LoadGeneratedAssembly(type defaultNamespace out implementation)

   if (assembly == null)

  

   this mapping = new XmlReflectionImporter(defaultNamespace) ImportTypeMapping(type null defaultNamespace)

   this tempAssembly = GenerateTempAssembly(this mapping type defaultNamespace)

  

   else

  

   this mapping = XmlReflectionImporter GetTopLevelMapping(type defaultNamespace)

   this tempAssembly = new TempAssembly(new XmlMapping[] this mapping assembly implementation)

  

  

   cache Add(defaultNamespace type this tempAssembly)

  

   为了加快运行速度 xmlserializer做了cache 在代码中 也许我们有N多的type 那么每个type在这里都做了一个assembly 都把assembly放到了cache中 这样 本来没问题 但是如果type有几千个 有几万个 那么就有几千几万个temp assembly出现 这些assembly都很小 也许只有 个字节 也许是 字节 但是注意的是 内存分配时 是按照 块 来分配的 假如说每个块最小为 k大小 那么即使只分配一个字节的内存 我们也要申请一个 k的page 那么 如果我们的小块非常非常多 那么我们身子缩小N倍后 你会发现内存里面四处都是小窟窿 这些窟窿加起来很大 但是别人就是不能用 因为这 k内存 必须要连续的块

  so 当我们发现w wp exe仅仅 百兆的时候 就报OOM了 就是这个原因

cha138/Article/program/net/201311/12615

相关参考

《One Of Them Girls》歌词全文及译文

《OneOfThemGirls》由AshleyGorley/BenJohnson/DallasDavidson/LeeBrice作词作曲,LeeBrice演唱,LeeBrice生于1980年,南卡罗来

知识大全 JVM Memory

JVMMemory  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ·StackMemory(栈内

关于ROM存储器(Read Only Memory),下列说法正确的是()

关于ROM存储器(ReadOnlyMemory),下列说法正确的是()A、存储的内容在联机操作时只能读出而不能写入或被修改B、不能作为输入缓冲区,但能作为输出缓冲区。C、能作为输入缓冲区,但不能作为输

关于ROM存储器(Read Only Memory),下列说法正确的是()

关于ROM存储器(ReadOnlyMemory),下列说法正确的是()A、存储的内容在联机操作时只能读出而不能写入或被修改B、不能作为输入缓冲区,但能作为输出缓冲区。C、能作为输入缓冲区,但不能作为输

DMA方式,即直接存储器访问(Direct Memory Access)方式。这种方式中()

DMA方式,即直接存储器访问(DirectMemoryAccess)方式。这种方式中()A、数据在外部设备和主存储器间通过总线直接传送,不需CPU干预。B、CPU控制在外部设备和主存储器间的数据传送。

DMA方式,即直接存储器访问(Direct Memory Access)方式。这种方式中()

DMA方式,即直接存储器访问(DirectMemoryAccess)方式。这种方式中()A、数据在外部设备和主存储器间通过总线直接传送,不需CPU干预。B、CPU控制在外部设备和主存储器间的数据传送。

知识大全 c#学习体会:使用 ref 和 out 传递数组

  c#学习体会:使用ref和out传递数组(downmoon)希望与大家分享与所有的out参数一样在使用数组类型的out参数前必须先为其赋值即必须由接受方为其赋值例如public stat

知识大全 nginx 504 Gateway Time-out错误解决办法

nginx504GatewayTime-out错误解决办法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 ASP.NET教程:Ref和Out关键字异同

ASP.NET教程:Ref和Out关键字异同  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  类型

知识大全 but of 是什么意思

butof是什么意思?butof不是什么固定搭配是根据前半句出来的用法如:Lifeisn’tamatterofmilestones,butofmoments...but依然表示转折的意思,of前面省略