windbg分析一次大查询导致的内存暴涨
项目上反馈了一个问题,就是在生产环境上,用户正常使用的过程中,出现了服务器内存突然暴涨,客户有点慌,想找下原因。
讲道理,内存如果是缓慢上涨一直不释放的话,应该是存在内存泄漏的,这种排查起来比较困难,还得找开发一块看;但像这种突然暴涨的,肯定是把某些大对象放到内存里了,而最有可能的,就是大查询了,比如把几百万数据查出来这种,但这种一般等用户用完这个功能内存就会降下来。
环境:IIS+.net framework。发现是w3wp进程一直在涨内存,也就是iis,确实是程序的锅。
分析内存问题的话,一般是在持续上涨的过程中,多抓几个dump,看看哪些对象没释放,便于分析,这次用户只抓了一个dump,要不然太大了,传到我本机也费事。
那就开始分析吧。
首先找了个本地测试环境,用windbg加载dump,加载分析文件,幸运的是,.loadby sos clr一次成功了,后续分析都没啥问题,不用再从客户那边拷贝sos,clr这些文件;
这是用户正常业务场景的dump,也不知道当时多少人用,都在干什么,既然是内存问题,先看下内存中的对象情况吧:
!dumpheap -stat

果不其然,出现了DataRow的影子,估计是有个大查询没跑了。但是是什么场景?哪个sql?查出来多少数据?这个得继续分析了。
需要注意的是,抓这个dump的时候,内存3g多,dump大小也3g多,但是DataRow这个对象总共才46M,为什么要看这个对象,不看其他的呢?
要知道,分析的话,从占用大的对象开始分析是没问题,但是得看这个对象是不是比较特殊,像是上边占用最高的是string,1g多,但是string太普遍了,数量多也正常,而且不好分析,但DataRow这个肯定是访问数据库了,这种对象好分析。
再就是,为什么才46M,这个涉及到托管内存和非托管内存了。c#是基于.net的高级编程语言,所谓的托管,其实是指内存的托管,就是当写代码需要new一个新对象的时候,是不需要考虑内存申请与销毁的,.net自动给你做了,所以,当你抓了一个6g的dump,可能里边的托管内存才2g,剩余4g非托管内存里的东西从windbg是看不到的,非托管内存的增长,肯定是由托管代码引起的,所以这个地方虽然DataRow只有46M,但是由这个引起的内存增长是不可知的。
那接下来就看看工作线程数和堆栈吧,对当时的业务场景、使用人数大概有个了解:
!threads -special

工作线程数不是很多,说明同时使用的人不多,应该不会有太大的压力,所以可能是某一个或者某几个线程引起的,那就看下堆栈情况,大致了解下使用场景,猜一下是哪个场景引起的:
~* e!clrstack 打印下所有线程的堆栈
本来工作线程就不多,有业务含义并且和数据库相关的堆栈就更少了,看了下,大致有三个场景:
一个貌似是在判断权限:

一个貌似是个财务的往来单位查询:

还有一个貌似是财务的凭证查询:

具体是哪个引起的就得继续分析了,可以分别进入这三个线程,看下线程里的对象情况。
比如,切换到往来单位查询的那个线程里(线程id是107),然后通过!dso命令查看下当前线程的对象:
~107 s
!dso

直接就看到一个sql了,看下这个线程里的DataRow吧,看看它是不是它的锅:
!do 0000006231d5af28

查看下所在的DataTable信息:
!do 0000006027566878

从elementColumnCount能看出来,当前是查询出来了89列;看的时候,要看下Type列,看看当前的对象类型,哪些是你需要和关注的。
然后再看recordManager,看下查询出来的记录信息,也就是行信息:
!do 0000006027566b08

recordCapacity,行容量,524288,即查询出来的行为52w。
至此,应该明了了,就是往来单位查询场景,上边的那个sql(当然也可以通过!dso中sqlCommand对象查看Text,确认具体的sql),查询出来了52w行,89列,导致的内存暴涨。
后来通过跟开发与用户确认,确实是这个查询界面上,没有选具体的单位,然后关联了一张600w数据的表,最终查出了52w行数据导致的。实际用户的业务场景是需要具体单位的,这种场景没做跨单位查询的权限控制,用户又恰巧没选单位,所以出现了这个问题。后来开发把单位加了必选,该问题解决。
windbg分析一次大查询导致的内存暴涨的更多相关文章
- apache不断占内存过大,导致虚拟机内存不足,处理方法。
我用512M的vps,访问量不大,但内存占用很大,甚至宕机. 我用top,然后shitf+m发现,httpd占用内存极大.经过网上找资料设置后,用过一段时间终于没再出现内存问题了. 首先查找配置文件的 ...
- 利用windbg分析崩溃,句柄泄漏,死锁,CPU高,内存泄漏
Windbg的一些简单使用命令 一.崩溃 1. 输入.ecxr;kbn得到崩溃的堆栈 其中源代码如下 2. 查看堆栈和源代码,发现第0帧导致崩溃,代码也是本地代码 输入.frame 0,切到第0 ...
- 利用Windbg分析Magicodes.IE一次错误编写导致内存剧增
由于这近一年时间一直忙于写书和工作,一直没有水文,但是近期有几位朋友使用我们的Magicodes.IE反馈在导出过程中内存暴涨...好吧,不管怎样,不能苦了我们朋友,接下来我们通过windbg来看一下 ...
- 揪出“凶手”——实战WinDbg分析电脑蓝屏原因
http://www.appinn.com/blue-screen-search-code/ 蓝屏代码查询器 – 找出蓝屏的元凶 11 文章标签: windows / 系统 / 蓝屏. 蓝屏代码查询器 ...
- Windbg分析高内存占用问题
1. 问题简介 最近产品发布大版本补丁更新,一商超客户升级后,反馈系统经常奔溃,导致超市的收银系统无法正常收银,现场排队付款的顾客更是抱怨声声.为了缓解现场的情况, 客户都是手动回收IIS应用程序池才 ...
- 《MySQL》一次MySQL慢查询导致的故障
本文转载自 http://www.jb51.net/article/70955.htm 我们知道分析MySQL语句查询性能的方法除了使用EXPLAIN 输出执行计划,还可以让MySQL记录下查询超过指 ...
- Android大图片导致内存问题小结
在网上看了部分Android中OOM的问题,现在根据理解,做一下笔记. Android OOM 产生的几种原因 1. 程序中使用了太多自己创建的Bitmap. 这种情况通常是最好解决的. 因为你明白你 ...
- 关于ODP.NET连接数监控及相应的windbg分析提示
1.关于ODP.NET的Windows计数器问题 使用微软的缺省驱动时,可以通过windows性能监视器很方便的监控数据库连接数,选择.NET Data Provider for Oracle/Sql ...
- Windbg分析蓝屏Dump文件
一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...
随机推荐
- 工作中遇到的SQL
1.根据a表中的字段col,修改b表中的col UPDATE a INNER JOIN b ON a.id = b.id SET b.col = xx WHERE a.col = xx 2.模糊查询 ...
- 【Leetcode】287. 寻找重复数(数组模拟链表的快慢指针法)
寻找重复数 根据题意,数组中的数字都在1~n之间,所以数字的范围是小于数组的范围的,数组的元素可以和数组的索引相联系. 例如:nums[0] = 1 即可以将nums[0]作为索引 通过nums[0] ...
- String与包装类_字节数组_字符数组间的转换
1.字符串与基本数据类型,包装类之间的转换 2.字符串与字节数组间的转换 3.字符串与字符数组间的转换 4.String与StringBuffer ①String---->StringBuffe ...
- echarts实现漏斗转化率图表效果
1.在用echarts实现图表的旅途中遇到这样一个需求,用柱图展示漏斗转化效果,下图展示: 别的不多说了,就说解决方式吧,用的series中的markpoint来实现. option.series[0 ...
- 01 . Mysql简介及部署
Mysql数据库简介 什么是数据? 数据(data)是事实或观察的结果,是对客观事物的逻辑归纳,是用于表示客观事物的未经加工的原始素材,数据是信息的表现形式和载体,可以是符号,文字,数字,语音,图 ...
- Java-接口(另类抽象)
1.1 特点 用interface定义 接口中所有成员变量都默认是由public static final修饰的 接口中所有方法都默认是由public abstract修饰的 接口没有构造器 接口采用 ...
- Java 第十一届 蓝桥杯 省模拟赛 户户通电(图算法)
户户通电 题目 问题描述 2015年,全中国实现了户户通电.作为一名电力建设者,小明正在帮助一带一路上的国家通电. 这一次,小明要帮助 n 个村庄通电,其中 1 号村庄正好可以建立一个发电站,所发的电 ...
- Java实现洛谷 P1873 砍树(StreamTokenizer+IO+二分)
P1873 砍树 输入输出样例 输入 5 20 4 42 40 26 46 输出 36 PS: get新知识,以前只知道STringTokenizer并没有了解过StreamTokenizer,这次才 ...
- SQK Server实现 LeetCode 175 组合两个表
175. 组合两个表 SQL架构 表1: Person +-------------+---------+ | 列名 | 类型 | +-------------+---------+ | Person ...
- Java实现 LeetCode 85 最大矩形
85. 最大矩形 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积. 示例: 输入: [ ["1","0","1 ...