翼度科技»论坛 编程开发 .net 查看内容

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

14

主题

14

帖子

42

积分

新手上路

Rank: 1

积分
42
一:背景

1. 讲故事

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

1. 捕获dump中的异常

一般来讲别人说的只是一个参考,我们需要自己到dump中去验证,可以用 !t 观察下。
  1. 0:000:x86> !t
  2. ThreadCount:      61
  3. UnstartedThread:  0
  4. BackgroundThread: 52
  5. PendingThread:    0
  6. DeadThread:       3
  7. Hosted Runtime:   no
  8.                                                                          Lock  
  9.        ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
  10.    0    1 9310 004e24f8     26020 Preemptive  00000000:00000000 004d94e0 0     STA System.Runtime.InteropServices.COMException 42b57774 (nested exceptions)
  11.    ...
  12. 0:000:x86> !PrintException /d 42b57774
  13. Exception object: 42b57774
  14. Exception type:   System.Runtime.InteropServices.COMException
  15. Message:          存储空间不足,无法处理此命令。 (Exception from HRESULT: 0x80070008)
  16. InnerException:   <none>
  17. StackTrace (generated):
  18.     SP       IP       Function
  19.     00000000 00000001 mscorlib_ni!System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32, IntPtr)+0x2
  20.     003FAC0C 6F5655C9 mscorlib_ni!System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32, IntPtr)+0x9
  21.     003FAC10 55171671 PresentationCore_ni!MS.Internal.Text.TextInterface.Native.Util.ConvertHresultToException(Int32)+0x702961
  22.     003FAC24 54A56129 PresentationCore_ni!MS.Internal.Text.TextInterface.FontFace.GetDesignGlyphMetrics(UInt16*, UInt32, MS.Internal.Text.TextInterface.GlyphMetrics*)+0x79
  23.     003FAC60 54A73B77 PresentationCore_ni!System.Windows.Media.GlyphTypeface.GlyphMetrics(UInt16*, Int32, MS.Internal.Text.TextInterface.GlyphMetrics*, Double, System.Windows.Media.TextFormattingMode, Boolean)+0x47
  24.     ...
复制代码
从卦中信息看确实抛了一个 COMException 异常,并且真的有这么一条错误信息 存储空间不足,无法处理此命令,而且从调用栈来看貌似是wpf在处理 字形信息,一般来说这种代码是千锤百炼不会出任何问题的。
作为现代化的程序员,必须通过 百度搜索 寻找一下天涯沦落人,通过搜索得知大概有两种情况:

  • 硬盘存储空间不足所致
  • 内存不足所致

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

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

要想排查这种情况只能观察进程的 MEM_COMMIT 指标,使用 !address -summary 。
  1. 0:000:x86> !address -summary
  2. ...
  3. --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
  4. MEM_COMMIT                             3773          6e617000 (   1.725 GB)  89.86%   86.24%
  5. MEM_RESERVE                             702           c4c6000 ( 196.773 MB)  10.01%    9.61%
  6. MEM_FREE                                667           5513000 (  85.074 MB)            4.15%
  7. ...
  8. --- Largest Region by Usage ----------- Base Address -------- Region Size ----------
  9. Heap32                                      23470000            fd0000 (  15.812 MB)
  10. <unknown>                                   474b0000           19c4000 (  25.766 MB)
  11. Image                                       2fbf1000           1180000 (  17.500 MB)
  12. Free                                        7355b000            1a5000 (   1.645 MB)
  13. Stack32                                       c50000             fd000 (1012.000 kB)
  14. Stack64                                       5a0000             39000 ( 228.000 kB)
  15. Other                                         8e0000            181000 (   1.504 MB)
  16. TEB64                                       7ee37000              2000 (   8.000 kB)
  17. Heap64                                        120000             65000 ( 404.000 kB)
  18. TEB32                                       7ee39000              1000 (   4.000 kB)
  19. Other32                                       290000              1000 (   4.000 kB)
  20. PEB64                                       7efdf000              1000 (   4.000 kB)
  21. PEB32                                       7efde000              1000 (   4.000 kB)
  22. ...
复制代码
从卦中的信息看,当前程序提交内存是 1.7G ,看到这个值马上就想到了 2G虚拟地址,那这个程序是不是x86的呢?除了观察内存地址,也可以通过观察 PE 头获知。
  1. 0:000:x86> lm
  2. start    end        module name
  3. 01380000 01450000   xxxWinApp C (no symbols)      
  4. 0:000:x86> !dh xxxWinApp
  5. File Type: EXECUTABLE IMAGE
  6. FILE HEADER VALUES
  7.      14C machine (i386)
  8.        3 number of sections
  9. 654073AD time date stamp Tue Oct 31 11:25:33 2023
  10.        0 file pointer to symbol table
  11.        0 number of symbols
  12.       E0 size of optional header
  13.      102 characteristics
  14.             Executable
  15.             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】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具