admin 管理员组文章数量: 887042
2024年2月18日发(作者:宁波网络公司)
VM50内存溢出原因分析-20091118
1. 背景
VM50出现内存溢出,性能组对此问题进行了跟踪。
2. 前期分析
在内存溢出时抓取了Dump文件,查看heap信息,有一项不太正常。
793043b8 1047476 12569712 n
79307c84 535721 12857304 l
2f52dda8 42423 14084436 ster
2e14c210 74907 16479540 ute
79332178 1032867 16525872 64
查找一个ItemMaster对象的引用链
0:022> !gcroot a251b17c
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Scan Thread 12 OSTHread 14e0
ESP:202ed3c:Root:02b32290()->
aaeedbf4(ionContext)->
aaeedc18(calCallContext)->
aaeed894(ntext)->
aaeec144(orkerRequestInProcForIIS6)->
02b51d74(rkerRequest+EndOfSendNotification)->
02b51a48(ntime)->
02b51afc(tTimeoutManager)->
02b51b20([])->
02b51c18(LinkList)->
5197174c(tTimeoutManager+RequestTimeoutEntry)->
519711a4(ntext)->
06b30044()->
0ab6b8c0([][])->
0ab6b8d4([])->
51973d98(Dictionary)->
51973dac(ctionary)->
51973dc8(ctionary+DictionaryNode)->
51973ddc(ctionary+DictionaryNode)->
51973dfc(ctionary+DictionaryNode)->
51973df0(orStack)->
5197f5a8(List`1[[orContext, ]])->
5198fbe8(ListNode`1[[orContext, ]])->
5198fb50(orContext)->
5198fb60(Dictionary)->
5198fb74(ctionary)->
5198fb90(ctionary+DictionaryNode)->
5198fbb4(ctionary+DictionaryNode)->
5198fbd4(ctionary+DictionaryNode)->
5198fc00(ctionary+DictionaryNode)->
519901d8(ctionary+DictionaryNode)->
990089c4(ctionary+DictionaryNode)->
99003e88(ctCache)->
99003cf8()->
99003df8(venging)->
99003e30(List`1[[ationBasket, ]])->
a1e72e08(ListNode`1[[ationBasket, ]])->
aac8bf2c(ListNode`1[[ationBasket, ]])->
0de096e8(ListNode`1[[ationBasket, ]])->
97824258(ListNode`1[[ationBasket, ]])->
97822f68(ationBasket)->
97822f88([])->
97823fc4(ationBasket+EliminationItem)->
a25281fc(tem)->
a25281a0(`1[[stableObject,
]])->
a25281d4(tionGuardList)->
a251b3ec(Relation)->
a251b3a8(Value)->
a251b17c(ster)
被HttpContext引用住了,看一下该HttpContext中包含的Url信息。
0:022> !do 51973ee8
Name:
MethodTable: 793308ec
EEClass: 790ed64c
Size: 670(0x29e) bytes
(C:WINDOWSassemblyGAC_32mscorlib2.0.0.0__)
String:
vm50:80/Portal/ufsoft/?lnk=99f1b00a-1dc8-45e3-9331-2352aeeeac3e&chromeType=4&ShowType=ShowModal&ParentTaskID=e347e1a9-8503-42fb-8ada-aa5bce268399&EntityFullName=ster&CardFormID=053a1be3-2c56-428b-b221-b5291644f2cb&__sk=__SK61558&__curOId=1017&ShowAtlasModalDialog=true
程得恩协助确认了该功能点是料品列表的批量修改功能,并重现了该问题。
3. 分析过程
重现该问题后,收集到了该操作的调用栈。
。。。
1b47e05c 7fa25fc4 ()
1b47e070
()
1b47e214 2dc770cb e()
1b47e28c a63877fe ()
1b47e2ac a6386f6e
a6387e3e
(nDataContract, , , `1
`1
1b47e384 a6386d09
(xt,
`1
, , `1
`1
。。。(部分内容,完整见附件)
重点检查黄色部分的代码。
首先检查检查方法中的IDs
0:036> !do 0x0dfd4da4
Name: odifyBP
MethodTable: 55597298
EEClass: 555dcbd0
Size: 24(0x18) bytes
(D:portal-2009-11-18(v2.0))
Fields:
MT Field Offset Type VT Attr Value Name
793308ec 4000131 4 0 instance 0dfb7a1c
entityFullName
793308ec 4000132 8 0 instance 0dfd41bc oPath
00000000 4000133 c 0 instance 0dfd4164 entityIDs
00000000 4000134 10 0 instance 0dfd4dbc
modifyPropValues
0:036> !do 0dfd4164
Name: `1[[64, mscorlib]]
MethodTable: 793227ac
EEClass: 790e7478
Size: 24(0x18) bytes
(C:WINDOWSassemblyGAC_32mscorlib2.0.0.0__)
Fields:
MT Field Offset Type VT Attr Value Name
793320c8 40009d8 4 64[] 0 instance 0fb53f48 _items
79332b38 40009d9 c 32 1 instance 0 _size
79332b38 40009da 10 32 1 instance 0 _version
79330508 40009db 8 0 instance 00000000 _syncRoot
793320c8 40009dc 0 64[] 0 shared static
_emptyArray
Size是0,因此代码应该是走到了代码图的红色部分,继续检查list的值
0:024> !do 5199c82c
Name: `1[[stableObject,
]]
MethodTable: 2e141770
EEClass: 2e133b1c
Size: 28(0x1c) bytes
(C:meworkv2.0.50727Temporary
Filesportal863bec524df0d36assemblydl3efd6fb4ee89e06ba_)
Fields:
MT Field Offset Type VT Attr Value Name
7932a768 4000021 4 ... 0 instance 5199c848 innerList
00000000 4000022 8 0 instance 00000000 delLists
793308ec 4000023 c 0 instance 02b301d0
childAttrName
2303f0f8 4000024 10 ...PersistableObject 0 instance 00000000 parentPO
793308ec 4000025 14 0 instance 02b301d0
parentAttrName
0:024> !do 5199c848
Name: ist
MethodTable: 7933291c
EEClass: 790ee61c
Size: 24(0x18) bytes
(C:WINDOWSassemblyGAC_32mscorlib2.0.0.0__)
Fields:
MT Field Offset Type VT Attr Value Name
793040bc 40008fb 4 [] 0 instance 14ff0130 _items
79332b38 40008fc c 32 1 instance 42253 _size
79332b38 40008fd 10 32 1 instance 42253 _version
79330508 40008fe 8 0 instance 00000000 _syncRoot
793040bc 40008ff 1c4 [] 0 shared static emptyArray
Size是42253项,就是这个了,在中,将循环42253次调用方法,进行ItemMaster的Modify操作,由于最外层的list一直拿着ItemMaster的强引用,因此必须要等到全部ItemMaster都修改完成后,才能被释放。
4. 结论
对于FindAll返回对象过多,导致内存OOM的问题,一般要求开发转而使用DataReader解决。但是,从DataReader得到的是DB对象,在编程的方便性上远较BE对象为差。使用Page加载Entity对象的方式,内存占用可以保持在一个较小的水平,这非常好。但可惜的是获取下一页又要执行一次数据库查询,带领额外的数据库消耗。
因此,我们希望将Entity对象的便利和DataReader的高效结合起来,由平台支持EntityDataReader方式操纵数据。
针对本案例,由于只需要取Entity的ID属性,应该使用EntityDataQuery以Reader方式只获取Entity的ID属性。
版权声明:本文标题:2.VM50内存溢出原因分析-20091118 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1708211505h516806.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论