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行数据导致的。实际用户的业务场景是需要具体单位的,这种场景没做跨单位查询的权限控制,用户又恰巧没选单位,所以出现了这个问题。后来开发把单位加了必选,该问题解决。

原文地址:https://www.cnblogs.com/Invokerr/p/11027742.html

时间: 2024-11-09 04:38:40

windbg分析一次大查询导致的内存暴涨的相关文章

揪出“凶手”——实战WinDbg分析电脑蓝屏原因

http://www.appinn.com/blue-screen-search-code/ 蓝屏代码查询器 – 找出蓝屏的元凶 11 文章标签: windows / 系统 / 蓝屏. 蓝屏代码查询器可以帮你查出引起蓝屏的故障原因并可以到微软知识库中查询解决方案,和之前的 BlueScreenView 配合是很好的蓝屏故障排除组合.@Appinn 使用时只需填入错误代码的简写即可,另外在支持中心中有关于蓝屏原因分析的文章链接,有兴趣的童鞋可以去看看..  官方网站 | 来自小众软件 http:/

Windbg 分析CPU上涨

症状: 下班前,收到报警邮件.一个应用的两台服务器CPU 过高.打开监控一看CPU都100了.没找到原因之前,先抓好DUMP 然后重启应用程序池. !threadpool 可以看到CPU 利用率 !runaway 查看运行的线程和运行时间 解决CPU 高的问题,应该从运行的线程上分析.分析它们都在干什么,哪个线程一直占用CPU运行时间 ~threadid s  切换到运行时间最长的几个线程 k   显示当前线程的call stack 发现都是在GC线程(SVR::gc_heap::gc_thre

Windbg 分析线程堵塞

症状: 端午发布后,服务器出现大量报错日志,并且平均响应时间不断上升.重启机器后立刻恢复正常,但还是运行一段时间后,响应时间又开始上升. 从报错日志中发现很多DB连接池满的错误.导致这种错误一般有两个原因: 1:SQL 执行完后,DbConnection 及时没有释放. 2:SQL 执行慢,占用了大量 DbConnection . 通过对代码彻底扫描,发现有几个 DataReader 没有显示关闭的地方.但这些都是运行很久老代码应该不是引用这次现象的原因.修改代码重新上线后的确没有得到改善. 继

Windbg分析高内存占用问题

1. 问题简介 最近产品发布大版本补丁更新,一商超客户升级后,反馈系统经常奔溃,导致超市的收银系统无法正常收银,现场排队付款的顾客更是抱怨声声.为了缓解现场的情况, 客户都是手动回收IIS应用程序池才能解决. 这样的后果是很严重的,接到反馈,第一时间想到的是加内存吧,这样最快.但是客户从8G-->16G-->32G,只是延长了每次奔溃的时间,但是并没有解决系统卡顿的问题.到这里,也基本猜测了问题所在了,肯定是什么东西一直在吃内存且得不到释放.这种问题,也就只能打Dump分析了. 2. 打Dum

View的post方法导致的内存泄漏分析

简述: 写这篇文章的缘由是最近项目中查内存泄漏时,发现最终原因是由于异步线程调用View的的post方法导致的. 为何我会使用异步线程调用View的post方法,是因为项目中需要用到很多复杂的自定义布局,需要提前解析进入内存,防止在主线程解析导致卡顿,具体的实现方法是在Application启动的时候,使用异步线程解析这些布局,等需要使用的时候直接从内存中拿来用. 造成内存泄漏的原因,需要先分析View的post方法执行流程,也就是文章前半部分的内容 文章内容: View#post方法作用以及实

大数据导致DataReader.Close超时的异常

公司一个数据抓取的程序,数据量极大,读取数据的用IDataReader的Read方法来进行数据处理,在测试的时候我想跑一部分数据后跳出循环,即break; 然后关闭datareader,但是在执行datareader.close()方法的时候出现了“超时异常”的错误, 查看了一下MSDN对Close方法的说明的备注 如下: 当使用 SqlDataReader 将关联的 SqlConnection 用于任何其他用途时,必须显式调用 Close 方法. Close 方法填写输出参数的值.返回值和 R

WinDbg分析DMP文件方法完全攻略

前言:在C++实际开发过程中,开发出来的程序,一般情况下由开发人员进行单元测试,然后移交给测试人员进行测试.在开发人员测试出现的bug,我们可以直接在本地进行调试.如果测试人员测试出崩溃级别的bug,如果我们需要调试往往借助于vs提供的Remote Debugger工具进行远程调试(关于vs2010远程调试的方法,请参考http://blog.sina.com.cn/s/blog_a459dcf5010153o7.html),然是当程序在用户手中出现崩溃此时我们可以采用Remote Debugg

大查询对mha切换的影响

先说结论: 如果在线MHA切换,为了减少对系统的影响,应该先让实例只读,等待大查询结束之后,才开始切换,而更好的做法的,自动kill掉大查询,确保切换影响时间最少. (1)正常的MHA切换程序中,mha会调用FLUSH  NO_WRITE_TO_BINLOG TABLES这个语句: (2)这个时候,如果有大的查询在执行,mha就会需要等待.同事前天做了一次mha在线切换,切换的时候,当时有如下的语句正在执行: select gpl.ID, gpl.GAME, gpl.LOGIN_ACCOUNT,

使用Windbg分析蓝屏原因

序言:     当电脑频繁蓝屏时我们需要软件来查找蓝屏原因,此时可以使用Windbg软件对蓝屏文件进行分析查找原因. 工具:     1.WinDbg软件,有两种版本,可以参考我的上一篇文章:安装与配置windbg的symbol(符号) 方法/步骤:     1.首先我们要保证我们设置了蓝屏转储,这样当电脑蓝屏时,系统会以.dmp文件方式保留蓝屏故障原因,我们需要查询是否设置内存转储和蓝屏文件存放位置.右键单击桌面计算机图标--选择属性,单击高级系统设置,在启动和故障恢复栏中单击设置,在写入调试