另一种形式的OufOfMemoryException
内存中空闲空间不少,但是连续的空闲空间却只有100k。
0:000> !address -summary
PEB 7ffd3000 1000 ( 4.000 kb)
通过!address命令直接查看下内存分布情况,发现内存中全是如下形式
+ 7fce0000 7fce1000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fce1000 7fcf0000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fcf0000 7fcf1000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fcf1000 7fd00000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd00000 7fd01000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fd01000 7fd10000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd10000 7fd11000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fd11000 7fd20000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd20000 7fd21000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fd21000 7fd30000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd30000 7fd43000 13000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unknown>
+ 7fd43000 7fd50000 d000 MEM_FREE PAGE_NOACCESS Free
+ 7fd50000 7fd51000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fd51000 7fd60000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd60000 7fd61000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
+ 7fd61000 7fd70000 f000 MEM_FREE PAGE_NOACCESS Free
+ 7fd70000 7fd71000 1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>
查看其中内存内容,发现是GIF格式的图片占用了空间
0:000> dc 7fcf0000
7fcf0000 38464947 00786139 00f7001e 7b787200 GIF89ax......rx{
7fcf0010 dff5efe2 e8dcf2ec f3ede0ee d7f4eee1 ................
7fcf0020 aea5e9e4 e4ded2b2 9e918d86 bbb1aca8 ................
7fcf0030 8e8a83c0 9bebe6d9 d0c5a8a4 b1aca3d5 ................
7fcf0040 ddb5b1a7 e8dbefe9 dbd6caed a4c9c4b9 ................
7fcf0050 968eb2ad c8c3b899 c2beb9af c9bfd2cd ................
7fcf0060 7c7973ce debbb7ad 857ef0ea 9b988f88 .sy|......~.....
7fcf0070 96e7e1d5 9088a39e e8e2d694 8ed4cfc4 ................
通过如下命令查看这种形式的内存使用,居然有4873处,计算一下 (f000+1000) * 4873 = 319356928, 占用了300多MB空间,难怪空闲空间很多,但是连续的又这么少。
0:000> .shell -ci "!address" find /C "1000 MEM_MAPPED MEM_COMMIT PAGE_READONLY <unknown>"
4873
.shell: Process exited
一般来说<unknown>内存空间是被managed程序占用,查看一下finalizequeue,发现里面正好有4000多个bitmap
0x7ae3c9f8 4,884 117,216 System.Drawing.Bitmap
解决方法就是在使用完bitmap之后直接调用dispose释放掉unmanaged资源,不要等待finalize被调用。