为什么TimerThread中int64数组这么大

问题描述 投票:0回答:1

我正在调查 32 位进程中的 OutOfMemoryException, 以下统计数据引起了我的注意(大型 int64 数组):

!dumpheap -stat
........
707b251c        3       692500 System.Int64[]
6fa6b038    72151      2020228 System.Diagnostics.ProcessModule
6fa9b1a0    72151      2308832 System.Diagnostics.ModuleInfo
707fdd04     2404      3223807 System.Byte[]
707faea4    11990      5780152 System.Object[]
707fb37c     9847     16162530 System.Char[]
00c16a88    41026     19281740      Free
707fac04   183726     21698276 System.String
Total 758006 objects
0:000> !DumpHeap /d -mt 707b251c
 Address       MT     Size
02f5b9ec 707b251c       76     
02f7c198 707b251c       60     
03f40000 707b251c   692364     

Statistics:
      MT    Count    TotalSize Class Name
707b251c        3       692500 System.Int64[]
Total 3 objects
0:000> !gcroot 03f40000
Thread 4320:
*** WARNING: Unable to verify checksum for System.ni.dll
    1238ea6c 6fbedbd0 System.Net.TimerThread.ThreadProc() [f:\dd\NDP\fx\src\net\System\Net\_TimerThread.cs @ 707]
        edi:  (interior)
            ->  03dc3670 System.Object[]
            ->  03f40000 System.Int64[]

Found 1 unique roots (run '!GCRoot -all' to see all roots).

使用.Net Framework 4.8。 为什么TimerThread需要这么大的数组?

转储是由应用程序的“简化”制成的, 初始版本有更剧烈的数字(有更多线程(229 vs 32),应用程序域(~180 vs 0)加载):

!dumpheap -stat
..........
707b251c      387    105384412 System.Int64[]
.net multithreading garbage-collection windbg
1个回答
0
投票

终于找到了, 不确定 WinDbg 显示的 TimeThread 调用堆栈是否反映了现实,但是 重现它的最简单方法是使用 main 方法运行此类控制台应用程序:

var procs = System.Diagnostics.Process.GetProcessesByName("GetProcessesByName");
     Console.ReadKey();

然后获取转储,这在我的案例中显示

!dumpheap -stat
....
6fa595d0     7361       264996 System.Diagnostics.ThreadInfo
6fa595a4     7361       529992 
System.Diagnostics.NtProcessInfoHelper+SystemThreadInformation
7061251c        2      1003800 System.Int64[]
Total 19595 objects

所以看来奇怪的行为与 Process.GetProcessesByName 有关。 然而 Process.GetCurrentProcess() 不会在内存中产生任何 int64[] 占用空间。

© www.soinside.com 2019 - 2024. All rights reserved.