程序怎么跑着 就卡死,句柄泄漏,内存泄漏了

一:背景

1. 讲故事

上个月中旬,星球里的一位朋友在微信找我,说他的程序跑着跑着内存会不断的缓慢增长并无法释放,寻求如何解决 ?

44d707f0a8bca548e35f4fc28d93cd76.png

得,看样子星球还得好好弄!!!😂😂😂  不管怎么说,先上 windbg 说话。

二:Windbg 分析

1. 经验推理

从朋友的截图看,有大量的 8216 字节的 byte[],这表示什么呢?追随本系列的朋友应该知道,有一篇 某三甲医院 的内存暴涨的dump中,也同样有此 size= (8216-24=8192) 的 byte[] 数组, 他的问题是 Oracle 中读取某大字段时sdk里的 OraBuf 出了问题,换句话说,这肯定又是底层或者第三方库中的池对象搞出来的东西,接下来从 托管堆 看起。

2. 查看托管堆

0:000> !dumpheap -stat
Statistics:
00007ffe107248f0   483707     15478624 System.Threading.PreAllocatedOverlapped
00007ffe1079c160   483744     15479808 System.Threading.ThreadPoolBoundHandle
00007ffe1079cff8   483701     23217648 System.Threading._IOCompletionCallback
00007ffe106e7a90   483704     23217792 Microsoft.Win32.SafeHandles.SafeFileHandle
00007ffe1079b088   483703     30956992 System.IO.FileSystemWatcher+AsyncReadState
00007ffe1079ceb0   483707     34826904 System.Threading.OverlappedData
00007ffe1079ccb0   483707     34826904 System.Threading.ThreadPoolBoundHandleOverlapped
0000016c64651080   245652   1473128080      Free
00007ffe105abf30   488172   3977571092 System.Byte[]

扫完托管堆,卧槽 ,byte[] 没吸引到我,反而被 System.IO.FileSystemWatcher+AsyncReadState 吸引到了,毕竟被 System.IO.FileSystemWatcher 折腾多次了,它已经深深打入了我的脑海。。。毕竟让程序卡死,让句柄爆高的都是它。。。这一回八成又是它惹的祸,看样子还是有很多程序员栽在这里哈。

为做到严谨,我还是从最大的 System.Byte[] 入手,按size对它进行分组再按totalsize降序,丑陋的脚本我就不发了,直接上脚本的输出结果。

!dumpheap -mt 00007ffe105abf30
size=8216,count=483703,totalsize=3790M
size=8232,count=302,totalsize=2M
size=65560,count=6,totalsize=0M
size=131096,count=2,totalsize=0M
size=4120,count=11,totalsize=0M
size=56,count=301,totalsize=0M
size=88,count=186,totalsize=0M
size=848,count=16,totalsize=0M
size=152,count=85,totalsize=0M
size=46,count=242,totalsize=0M
size=279,count=38,totalsize=0M!dumpheap -mt 00007ffe105abf30 -min 0n8216 -max 0n8216 -short0000016c664277f0
0000016c66432a48
0000016c6648ef88
0000016c6649daa8
0000016c6649fb00
0000016c664a8b90
...

从输出结果看,size=8216byte[] 有 48w 个,然后脚本也列出了一些 8216 大小的 address 地址,接下来用 !gcroot 看下这些地址的引用。

0:000> !gcroot 0000016c664277f0
HandleTable:0000016C65FC28C0 (async pinned handle)-> 0000016C6628DEB0 System.Threading.OverlappedData-> 0000016C664277F0 System.Byte[]Found 1 unique roots (run '!gcroot -all' to see all roots).
0:000> !gcroot 0000016c667c80d0
HandleTable:0000016C65FB7920 (async pinned handle)-> 0000016C663260F8 System.Threading.OverlappedData-> 0000016C667C80D0 System.Byte[]

从输出中可以看到这些 byte[] 都是 async pinned,也就是当异步IO回来的时候需要给 byte[] 填充的存储空间,接下来我们看看如何通过 OverlappedData 找到源码中定义为 8192 大小的 byte[] 地方。

如果你了解 FileSystemWatcher ,反向查找链大概是这样的 OverlappedData -> ThreadPoolBoundHandleOverlapped -> System.IO.FileSystemWatcher+AsyncReadState -> Buffer[], 这中间涉及到 ThreadPool 和 SafeHandle 的绑定。

0:000> !do 0000016C663260F8
Name:        System.Threading.OverlappedData
MethodTable: 00007ffe1079ceb0
EEClass:     00007ffe107ac8d0
Size:        72(0x48) bytes
File:        C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.10\System.Private.CoreLib.dll
Fields:MT    Field   Offset                 Type VT     Attr            Value Name
00007ffe106e3c08  40009ce        8  System.IAsyncResult  0 instance 0000000000000000 _asyncResult
00007ffe104a0c68  40009cf       10        System.Object  0 instance 0000016c66326140 _callback
00007ffe1079cb60  40009d0       18 ...eading.Overlapped  0 instance 0000016c663260b0 _overlapped
00007ffe104a0c68  40009d1       20        System.Object  0 instance 0000016c667c80d0 _userObject
00007ffe104af508  40009d2       28                  PTR  0 instance 00000171728f66e0 _pNativeOverlapped
00007ffe104aee60  40009d3       30        System.IntPtr  1 instance 0000000000000000 _eventHandle
00007ffe104ab258  40009d4       38         System.Int32  1 instance                0 _offsetLow
00007ffe104ab258  40009d5       3c         System.Int32  1 instance                0 _offsetHigh
0:000> !do 0000016c663260b0
Name:        System.Threading.ThreadPoolBoundHandleOverlapped
MethodTable: 00007ffe1079ccb0
EEClass:     00007ffe107ac858
Size:        72(0x48) bytes
File:        C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.10\System.Private.CoreLib.dll
Fields:MT    Field   Offset                 Type VT     Attr            Value Name
00007ffe1079ceb0  40009d6        8 ...ng.OverlappedData  0 instance 0000016c663260f8 _overlappedData
00007ffe1079b818  40009c0       10 ...ompletionCallback  0 instance 0000016f661ab8a0 _userCallback
00007ffe104a0c68  40009c1       18        System.Object  0 instance 0000016c667ca0e8 _userState
00007ffe107248f0  40009c2       20 ...locatedOverlapped  0 instance 0000016c66326090 _preAllocated
00007ffe104af508  40009c3       30                  PTR  0 instance 00000171728f66e0 _nativeOverlapped
00007ffe1079c160  40009c4       28 ...adPoolBoundHandle  0 instance 0000000000000000 _boundHandle
00007ffe104a7238  40009c5       38       System.Boolean  1 instance                0 _completed
00007ffe1079b818  40009bf      738 ...ompletionCallback  0   static 0000016f661ab990 s_completionCallback
0:000> !do 0000016c667ca0e8
Name:        System.IO.FileSystemWatcher+AsyncReadState
MethodTable: 00007ffe1079b088
EEClass:     00007ffe107a9dc0
Size:        64(0x40) bytes
File:        C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.10\System.IO.FileSystem.Watcher.dll
Fields:MT    Field   Offset                 Type VT     Attr            Value Name
00007ffe104ab258  400002b       30         System.Int32  1 instance                1 <Session>k__BackingField
00007ffe105abf30  400002c        8        System.Byte[]  0 instance 0000016c667c80d0 <Buffer>k__BackingField
00007ffe106e7a90  400002d       10 ...es.SafeFileHandle  0 instance 0000016c66326028 <DirectoryHandle>k__BackingField
00007ffe1079c160  400002e       18 ...adPoolBoundHandle  0 instance 0000016c66326058 <ThreadPoolBinding>k__BackingField
00007ffe107248f0  400002f       20 ...locatedOverlapped  0 instance 0000016c66326090 <PreAllocatedOverlapped>k__BackingField
00007ffe1079b8c8  4000030       28 ...eSystem.Watcher]]  0 instance 0000016c66326078 <WeakWatcher>k__BackingField

上面的 <Buffer>k__BackingField 就是当初丢给 OverlappedData 作为 异步IO 读写的缓冲,然后看下 System.IO.FileSystemWatcher+AsyncReadState 的源码。

78f4c54619eff95265e8940fcff13ad8.png

有了这些原理之后,接下来就可以问朋友是否有对 appsettings 设置了 reloadonchange=true 的情况,朋友找了下代码,写法大概如下:

public object GetxxxFlag()
{string value = AppConfig.GetConfig("appsettings.json").GetValue("xxxx", "0");return new{state = 200,data = value};
}public class AppConfig
{public static AppConfig GetConfig(string settingfile = "appsettings.json"){return new AppConfig(settingfile);}
}public class AppConfig
{private AppConfig(string settingfile){_config = new ConfigurationBuilder().AddJsonFile(settingfile, optional: true, reloadOnChange: true).Build();_settingfile = settingfile;}
}

从源码逻辑看,我猜测朋友将  GetConfig 方法标记成 static 后就以为是单例化了,再次调用不会重复 new AppConfig(settingfile),所以问题就出在这里。

不过有意思的是,前面二篇的 FileSystemWatcher 都会造成程序卡死,那这一篇为啥没有呢?恰好他没有在程序根目录中放日志文件,不然的话。。。😄😄😄,可万万没想到逃过了卡死却没逃过一个 watcher 默认 8byte 空间的灵魂拷问。。。😂😂😂

三:总结

总的来说,设置 reloadOnChange: true 一定要慎重, 可能它会造成你的程序卡死,句柄泄漏,内存泄漏 等等!!!改进方案我就不说了,参考我前面的系列文章吧。

END

工作中的你,是否已遇到 ... 

1. CPU爆高

2. 内存暴涨

3. 资源泄漏

4. 崩溃死锁

5. 程序呆滞

等紧急事件,全公司都指望着你能解决...  危难时刻才能展现你的技术价值,作为专注于.NET高级调试的技术博主,欢迎微信搜索: 一线码农聊技术,免费协助你分析Dump文件,希望我能将你的踩坑经验分享给更多的人。

81733c584ec30dc5064882759b55c0a0.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

活久见!一美国大爷发明了永不掉链子的自行车,垂直踩踏即可驱动

全世界只有3.14 % 的人关注了爆炸吧知识©文丨 直观学机械、自行车网最近&#xff0c;一款能永不掉链子的自行车特别火&#xff0c;咱们今天来看看它长什么样。这款自行车据说是由美国洛杉矶的一位老大爷 Rodger Parker 设计的&#xff0c;名叫&#xff1a;NuBike。设计自行…

学习xss的一些记录(一)

最近正在学习关于xss的一些知识&#xff0c;作为一个前端开发者&#xff0c;这个知识也是基础的&#xff0c;以前也没怎么好好学习与总结&#xff0c;深感惭愧&#xff0c;接下来的几天时间好好补习下。 xss是什么 xss的全称是Cross Site Scripting&#xff0c;即跨站脚本。攻击…

使用Hot Chocolate创建ASP.NET Core GraphQL服务

GraphQL介绍GraphQL是一个用于API的查询语言&#xff0c;是一个使用基于类型系统来执行查询的服务端运行时。GraphQL对你的API中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余。Hot Chocolate介绍Hot Choc…

MFC中的文件读写技术

计算机室如何管理自身所存放着的大量的信息的呢&#xff1f;windows的磁盘管理程序为我们提供了一套严密而又高效的信息组织形式--硬盘上的信息是以文件的形式被管理的。 面向存储的文件技术 什么是文件&#xff1f;计算机中&#xff0c;一篇文章、一幅图片、一个程序等都是以文…

[转]十五分钟介绍 Redis数据结构

下面是一个对Redis官方文档《A fifteen minute introduction to Redis data types》一文的翻译&#xff0c;如其题目所言&#xff0c;此文目的在于让一个初学者能通过15分钟的简单学习对Redis的数据结构有一个了解。 Redis是一种面向“键/值”对类型数据的分布式NoSQL数据库系统…

为什么大部分男生比女生高?原因让你意想不到

全世界只有3.14 % 的人关注了爆炸吧知识古往今来&#xff0c;不论东西南北&#xff0c;男女之间的画风都是&#xff1a;这样的▼这样的▼大家可以看出一个早已成为常识的问题&#xff1a;男人普遍比女人要高、要强壮&#xff0c;说白了就是四肢发达。然而&#xff0c;这到底是为…

MyBatis --教程

2019独角兽企业重金招聘Python工程师标准>>> 本文参考如下这篇优秀文章 http://www.yihaomen.com/article/java/302.htm 一、什么是myBatis&#xff1f; myBatis是一个基于java的持久层框架&#xff0c;它支持普通SQL查询、支持存储过程和高级映射。它使用简单的XML…

System.Text.Json 中的 JsonExtensionData

System.Text.Json 中的 JsonExtensionDataIntro最近两天在排查我们 API 的一个问题&#xff0c;查看源码过程中发现 System.Text.Json 里有一个有意思的 JsonExtensionData在反序列化的时候&#xff0c;如果反序列化的 Model 中没有对应的属性信息&#xff0c;这些信息就会丢失…

“中科院博士后当辅警”,网友却吵翻了:家里有矿?

全世界只有3.14 % 的人关注了爆炸吧知识这两天的热搜上有一位小哥哥特别引人关注有人看到了发际线有人看到了书香门第的出身更多人留意到了他的学历和身份香港大学博士、中科院博士后四川公安一名辅警↓↓↓缪元颖&#xff0c;四川省成都市公安局高新区分局的一名辅警&#xff…

马的种类(七)

鄂伦春马<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />鄂伦春马产于大小兴安岭山区。繁殖性能好&#xff0c;在小群自由交配的情况下&#xff0c;有些母马一年产一驹。生长缓慢&#xff0c;6~7岁时才能结束生长发育期。一般在…

OAuth 2.0 的探险之旅

前言OAuth 2.0 全称是 Open Authorization 2.0, 是用于授权(authorization)的行业标准协议。OAuth 2.0 专注于客户端开发人员的简单性&#xff0c;同时为 Web 应用程序、桌面应用程序、移动设备应用等提供了特定的授权流程。它在2012年取代了 OAuth 1.0, 并且 OAuth 2.0 协议不…

SQL 分页查询语句大全即(查找第N到M条记录的方法)

SQL 分页查询语句大全即&#xff08;查找第N到M条记录的方法&#xff09; 第一种方法&#xff0c;我的原创方法 row2 表示分页行数 page1 表示页码 getnumrow*page select * from (select top row * from (select top getnum * from Newslist order by id desc) order by id …

揭开不一样的世界,这5部纪录片绝对不能错过!

纪录片一直都是增长见识又带给你力量的东西&#xff0c;你可能忙于学业、生活、工作而不能行万里路&#xff0c;但至少你还可以看纪录片&#xff0c;从一方屏幕看到整个世界。今天就为大家整理了5部高分纪录片&#xff0c;文末附领取方式&#xff0c;快收下吧~01与摩根弗里曼一…

算术几何平均matlab,算术-几何平均数——高斯的发现

“算术-几何平均数”既不是算术平均数&#xff0c;也不是几何平均数&#xff0c;由素有“数学王子”之称的德国数学家高斯首先发现和研究。算术-几何平均数&#xff0c;当然与“算术平均数”和“几何平均数”这两个概念有很深的关系。我们知道&#xff0c;但凡一个数学概念或定…

.NET Core TLS 协议指定被我钻了空子~~~

【导读】此前&#xff0c;测试小伙伴通过工具扫描&#xff0c;平台TLS SSL协议支持TLS v1.1&#xff0c;这不安全&#xff0c;TLS SSL协议至少是v1.2以上才行&#xff0c;想到我们早已将其协议仅支持v1.3&#xff0c;那应该非我们平台问题。近日&#xff0c;第三方合作伙伴再次…

Android之CheckBox复选框控件使用inelayout.xml Xml代码

linelayout.xml Xml代码<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android" android:layout_width"match_parent" android:layout_height&quo…

frame buffer编程--画点功能和新增字符串代替RGBT

&#xff08;一&#xff09;&#xff1a;写在前面 这一次进行了一个比较大的迭代&#xff0c;在这里我先把相对于上一个版本的改进做一个解释&#xff1a; 1:进一步完善画点&#xff0c;增加了使用字符串代替RGBT值2:实现字符串解析出RGBT值3:增加了画圆的算法4:进一步增强了代…

这篇博士毕业论文致谢句句诛心......

全世界只有3.14 % 的人关注了爆炸吧知识本文来源&#xff1a;学术志综合自小木虫、网络等&#xff0c;作者yechm AUT博士毕业论文感谢信&#xff1a;我出生的时候是一个下雪的深夜&#xff0c;我的父亲在床边生了一堆柴火&#xff0c;我的母亲躺在四周漏风的那间破屋角落的床上…

30分钟通过Kong实现.NET网关

什么是KongOpenrestry是一个基于Nginx与Lua的高性能平台&#xff0c;内部有大量的Lua库。其中ngx_lua_moudule使开发人员能使用Lua脚本调用Nginx模块。Kong是一个Openrestry程序&#xff0c;而Openrestry运行在Nginx上&#xff0c;用Lua扩展了nginx。所以可以认为Kong Openres…

Proxy模式简介和用例

在软件系统中&#xff0c;有些对象有时候由于某些原因&#xff08;比如对象创建开销很大&#xff0c;或者某些操作需要安全控制&#xff0c;或者需要进程外的访问&#xff09;&#xff0c;如果直接访问会给使用者或者系统结构带来很多麻烦&#xff0c;这时可以在客户程序和目标…