叢墨 发表于 2023-12-6 14:36:58

记一次 .NET 某零售管理系统 存储不足分析

一:背景

1. 讲故事

前几天有位朋友找到我,说他的程序会偶发性的报 存储空间不足,无法处理此命令 的错误,让我帮忙看下到底怎么回事,哈哈,人家是有备而来,dump都准备好了,话不多说,直接分析开干。
二:WinDbg 分析

1. 捕获dump中的异常

一般来讲别人说的只是一个参考,我们需要自己到dump中去验证,可以用 !t 观察下。
0:000:x86> !t
ThreadCount:      61
UnstartedThread:0
BackgroundThread: 52
PendingThread:    0
DeadThread:       3
Hosted Runtime:   no
                                                                         Lock
       ID OSID ThreadOBJ    State GC Mode   GC Alloc ContextDomain   Count Apt Exception
   0    1 9310 004e24f8   26020 Preemptive00000000:00000000 004d94e0 0   STA System.Runtime.InteropServices.COMException 42b57774 (nested exceptions)
   ...

0:000:x86> !PrintException /d 42b57774
Exception object: 42b57774
Exception type:   System.Runtime.InteropServices.COMException
Message:          存储空间不足,无法处理此命令。 (Exception from HRESULT: 0x80070008)
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    00000000 00000001 mscorlib_ni!System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32, IntPtr)+0x2
    003FAC0C 6F5655C9 mscorlib_ni!System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32, IntPtr)+0x9
    003FAC10 55171671 PresentationCore_ni!MS.Internal.Text.TextInterface.Native.Util.ConvertHresultToException(Int32)+0x702961
    003FAC24 54A56129 PresentationCore_ni!MS.Internal.Text.TextInterface.FontFace.GetDesignGlyphMetrics(UInt16*, UInt32, MS.Internal.Text.TextInterface.GlyphMetrics*)+0x79
    003FAC60 54A73B77 PresentationCore_ni!System.Windows.Media.GlyphTypeface.GlyphMetrics(UInt16*, Int32, MS.Internal.Text.TextInterface.GlyphMetrics*, Double, System.Windows.Media.TextFormattingMode, Boolean)+0x47
    ...从卦中信息看确实抛了一个 COMException 异常,并且真的有这么一条错误信息 存储空间不足,无法处理此命令,而且从调用栈来看貌似是wpf在处理 字形信息,一般来说这种代码是千锤百炼不会出任何问题的。
作为现代化的程序员,必须通过 百度搜索 寻找一下天涯沦落人,通过搜索得知大概有两种情况:

[*]硬盘存储空间不足所致
[*]内存不足所致

2. 是硬盘存储空间不足吗

要想验证是不是这种情况导致的,只能询问下朋友,据朋友反馈不存在这个问题,所以这条路就堵死了。
3. 是内存不足吗

要想排查这种情况只能观察进程的 MEM_COMMIT 指标,使用 !address -summary 。
0:000:x86> !address -summary
...
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_COMMIT                           3773          6e617000 (   1.725 GB)89.86%   86.24%
MEM_RESERVE                           702         c4c6000 ( 196.773 MB)10.01%    9.61%
MEM_FREE                              667         5513000 (85.074 MB)            4.15%
...
--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Heap32                                    23470000            fd0000 (15.812 MB)
<unknown>                                 474b0000         19c4000 (25.766 MB)
Image                                       2fbf1000         1180000 (17.500 MB)
Free                                        7355b000            1a5000 (   1.645 MB)
Stack32                                       c50000             fd000 (1012.000 kB)
Stack64                                       5a0000             39000 ( 228.000 kB)
Other                                       8e0000            181000 (   1.504 MB)
TEB64                                       7ee37000            2000 (   8.000 kB)
Heap64                                        120000             65000 ( 404.000 kB)
TEB32                                       7ee39000            1000 (   4.000 kB)
Other32                                       290000            1000 (   4.000 kB)
PEB64                                       7efdf000            1000 (   4.000 kB)
PEB32                                       7efde000            1000 (   4.000 kB)
...从卦中的信息看,当前程序提交内存是 1.7G ,看到这个值马上就想到了 2G虚拟地址,那这个程序是不是x86的呢?除了观察内存地址,也可以通过观察 PE 头获知。
0:000:x86> lm
start    end      module name
01380000 01450000   xxxWinApp C (no symbols)      

0:000:x86> !dh xxxWinApp

File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
   14C machine (i386)
       3 number of sections
654073AD time date stamp Tue Oct 31 11:25:33 2023

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
   102 characteristics
            Executable
            32 bit word machine从卦中的 32 bit word machine 来看,确实没有开大地址,看样子是受到了 2G 的虚拟地址限制。

不过说实话我真的佩服写这个软件的程序员,在上限 2G 的空间内,能将程序控制在 1.72G 都不崩,把内存压得严严实实,确实
来源:https://www.cnblogs.com/huangxincheng/archive/2023/12/06/17879166.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 记一次 .NET 某零售管理系统 存储不足分析