Out Of Memory的分析及诊断方法

作者&投稿:敛管 (若有异议请与网页底部的电邮联系)
~

  首先 什么是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了 就是这个原因

lishixinzhi/Article/program/net/201311/12615




承德县17648838637: outofmemory怎么解决 -
谭弦知甘: OutOfMemory(内存溢出)是一个程序员常见的错误类型. 解决办法:1、首先先确定是不是开启的程序太多,导致内存不足.我们可以打开任务管理器,把占用内存过多的应用关闭.或者直接重启电脑试试.2、试试加大虚拟内存(开启之前,看看游戏是否有最新版本,加大虚拟内存,会对系统带来一定影响),操作流程:这台电脑→属性→高级→性能设置→高级→虚拟内存更改.设置最小和最大为你的电脑内存的1.5到2倍就行了.3、如果还是不行,可以尝试一下dos命令来解决下,点击开始-运行,输入cmd.然后在输入命令:Bcdedit /set IncreaseUserVa 3072,完成之后,按Entel(回车)键确定即可.

承德县17648838637: 开机时出现Out of memory是什么意思? -
谭弦知甘: 是内存不足的意思,大概是你开的东西太多了,对于Windows中的内存不足的处理方法可参考如下资料: 如果在运行Windows应用程序时,出现“内存不足”的故障,可按下列方法进行检查和处理: 1、首先应检查Windows的资源使用情况,...

承德县17648838637: linux出现out of memory是什么问题 -
谭弦知甘: Linux出现out of memory就是新启动的程序运行所需要的内存,大于系统空闲的物理内存容量,Linux系统一般会直接对这个程序进行kill从而不让程序启动,如果无法加大物理内存(一般也不会因为偶尔的情况就去加大内存),可以尝试增加swap内存交换分区,swap分区相当于Windows系统里面的“虚拟内存”设置.

承德县17648838637: 如何定位OutOfMemory的根本原因 -
谭弦知甘: 分析工具1) 动态分析工具 jprofile2) 静态分析工具 a: 在启动java的时候加上参数-xx:+heapdumponoutofmemoryerror,这样如果由于oom导致jvm crash的时候可以便于我们分析,生成的heap dump文件名字的命名规范如下, java_pidxxxx.hprof ...

承德县17648838637: 运行软件出现out of memory -
谭弦知甘: out of memory的意思是内存不足,这里的内存指的是RAM不足,有可能是你同时运行了很多个程序,或是你的内存条容量很小,我的电脑右键——属性——常规选项,看右下角就知道你的内存是多少

承德县17648838637: xp系统玩cf弹出“out of memory”是为什么? -
谭弦知甘: out of memory是提醒你游戏的缓存记录丢失了,可能是因为系统升级的原因.一、out of memory是什么意思 out of memory英文意思是电脑内存不足,我们都清楚,电脑程序的运行不仅仅对电脑CPU进行消耗,同时对内存也会进行占用,当占用...

承德县17648838637: 电脑出现out of memory 是什么问题?
谭弦知甘: 可能是电脑的虚拟内存太小引起OUT OF MEMORY. 解决方法:右击我的电脑,高级→性能 设置→高级,更改虚拟内存-设置的数值一般为你的电脑内存的1倍较好

承德县17648838637: outofmemory是什么意思 -
谭弦知甘: OutOfMemory(内存溢出)是一个程序员常见的错误类型

承德县17648838637: 电脑出现out of memory 是什么问题` -
谭弦知甘: 这是因为你的电脑内存不足引起的,试一下加大虚拟内存 方法为右击我的电脑-高级-性能 设置-高级-更改虚拟内存-设置D盘最小和最大为你的电脑内存的1.5到2倍就行了 求采纳

承德县17648838637: Java OutOfMemoryError 的原因是什么,什么是Java native方法 -
谭弦知甘: OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存.说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网