游子吟

致力于.Net,致力于企业信息化工程!
Harvest = Hope + Struggle

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  105 随笔 :: 18 文章 :: 539 评论 :: 21万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

2019年5月10日

,问题产生
    项目采用Tomcat6.0为服务器,数据库为mysql5.1,数据库持久层为hibernate3.0,以springMVC3.0为框架,项目开发完成后,上线前夕进行稳定性拷机,测试数据为插入4条/S,更新4条/S,访问300次/S,前期运行速度顺畅,三天后就开始运行缓慢,访问量达到1500W次后以抛出Java heap space结束.
.问题分析
    1.前期分析为连接池内存溢出,期间优化了连接池参数,调整了tomcat线程参数,替换数据库连接池,问题依旧
    2.看来问题不是简单的参数配置,需要进行一点深入的研究分析了,在和同事研究了一些资料后,对JAVA的垃圾收集机制有了一定的了解,JVM的内存模型分为新生代和老生代,JDK本身提供了一个监视工具jconsole.exe,进入bin文件夹打开后,选择连接--tomcat--内存,可以开始监视JVM内存回收情况,通过一段时间的监视后,发现了老生代的内存回收存在异常.

从上图可以看出,每次回收的内存都比上一次少,可以判断老生代的内存发生了泄露.
    3.虽然知道了存在内存泄露,但是无法判断是哪里发生了泄露,为此我们需要把堆(dump)导出来进行分析,JDK也提供了导出工具jvisualvm.exe,启动后右键点击线程--堆Dump,可以导出Dump文件.
    4.使用MAT(MemoryAnalyzer)分析Dump文件,该工具的下载地址为:http://www.eclipse.org/mat,可以下载离线版,也可以集成到eclipse,使用很方便.打开该工具导入Dump文件,稍等一会,就可以得出MAT提供的分析报告

MAT指出了该Dump中一个HashMap的实例发生了内存泄露,占用了JVM819M的内存,继续点击Details可以得到更详细的信息

这个detail比较详细的指出了问题所在,一个叫viewCache的hashMap实例占用共859M内存,虽然每个实例只有几百字节,但是一共产生了134W个实例.
    5.分析出这个问题点,接下去就是排查代码问题了,排查代码得知该项目使用springMVC,其中viewCache是spring中使用的一个视图缓存,在项目中如一个处理视图跳转的代码:

LinkedList list = this.getPathParam(mvValue);
    for (int i = 0; i < list.size(); i++) {
     String paramName = (String) list.get(i);
     String paramValue = null;
     paramValue = RequestUtils.getParamString(map, paramName);
     paramValue = paramValue == null ? "" : paramValue;
     mvValue = StringUtils.replace(mvValue, "#" + paramName+"#", paramValue);
   }
    return new ModelAndView(mvValue); 

由于paramValue每次都是动态生成的uuid,造成了每次的mvvalue都不同,这样每次都会生成一个不一样的视图,这样的视图累积到100多W个的时候,终于把tomcat撑暴了.百度了一下,果然也已经有人注意到了这个问题:http://jackyrong.iteye.com/blog/1744342.
    6.知道了问题所在后,就可以修改代码了,我们需要将ModelAndView的视图名称固定,动态参数可以通过ModelAndView提供的addObject方法传入,修改后的代码如下:

      //判断如果视图名称包含"snms_result.jsp",则将视图名称返回值统一,解决因动态产生视图名称过多产生的内存泄露问题, by feitianbubu 2013年5月27日 11:21:31
    ModelAndView mv=new ModelAndView(mvValue);
    LinkedList list = this.getPathParam(mvValue);
    for (int i = 0; i < list.size(); i++) {
     String paramName = (String) list.get(i);
     String paramValue = null;
     paramValue = RequestUtils.getParamString(map, paramName);
     paramValue = paramValue == null ? "" : paramValue;
     mv.addObject("id", ",'"+paramValue+"'");
    }
    return mv;

7. 代码commit SVN,发布拷机,观察内存回收情况

(为了更快模拟环境采用1000次/S插入数据和1000次/S读取数据,所以GC会比较频繁)
可以看出老生代内存得到有效回收,内存泄露的问题得到解决 

posted @ 2019-05-10 08:45 巴山游子 阅读(2285) 评论(0) 推荐(0) 编辑

2019年5月9日

摘要: 1、内存溢出:你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,出现溢出。 2、内存泄漏:你用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是因为一直被某个或某些实例所持有导致 GC 不能回收,也就是该被释放的对象没有释放。 阅读全文
posted @ 2019-05-09 17:24 巴山游子 阅读(1784) 评论(0) 推荐(0) 编辑

2019年5月6日

摘要: 一个简单且神奇的公式 今天的故事,从一个公式开始讲起。这是一个既简单又神奇的公式。说它简单,是因为它一共只有 3 个字母。而说它神奇,是因为这个公式蕴含了博大精深的通信技术奥秘,这个星球上有无数的人都在为之魂牵梦绕。 阅读全文
posted @ 2019-05-06 22:48 巴山游子 阅读(415) 评论(0) 推荐(0) 编辑

摘要: 今天,我是来“吹NB”的。嗯,标题已经剧透了,这个NB,就是NB-IoT。 在过去的一年多,NB-IoT真的可以说是大红大紫。在通信圈里,除了说5G,就是说物联网。如果说物联网,八成就是在说NB-IoT。 在目前5G还没来的情况下,NB-IoT基本上是独领风骚、风光无限。 阅读全文
posted @ 2019-05-06 22:46 巴山游子 阅读(661) 评论(0) 推荐(0) 编辑

2016年3月24日

摘要: SQL Server 2014 In-Memory 介绍 阅读全文
posted @ 2016-03-24 22:26 巴山游子 阅读(292) 评论(0) 推荐(0) 编辑

2016年1月14日

摘要: SQL Server Profiler的中文意思是SQL Server事件探查,一个Sql的监视工具,可以具体到每一行Sql语句,每一次操作,和每一次的连接。感觉这个工具的作用还是很大的,给大家分享一下,对于新手了解Sql语句的写法和提高语句的性能方法有很大的帮助。 阅读全文
posted @ 2016-01-14 08:46 巴山游子 阅读(353) 评论(0) 推荐(0) 编辑

2015年10月1日

摘要: 如题,参见:http://www.cnblogs.com/gaizai/archive/2011/11/18/2254445.htmlhttp://www.cnblogs.com/gaizai/p/3288354.html 阅读全文
posted @ 2015-10-01 15:58 巴山游子 阅读(263) 评论(0) 推荐(0) 编辑

2015年5月14日

摘要: 在使用SQL Server 的过程中,用户遇到的最多的莫过于连接问题了。本文将深度讨论SQL Server 连接问题的方方面面,希望能帮你彻底解决SQL server 的连接问题。 SQL Server 支持的通讯协议很多,如命名管道(Named Pipes)、TCP/IP 套接字、共享内存(Shared Memory)等。由于最常用的是前两种即命名管道和TCP/IP套接字,所以我们主要讨论这两种协议的连接问题。先来讨论命名管道,然后我们再讨论TCP/IP。 阅读全文
posted @ 2015-05-14 10:35 巴山游子 阅读(958) 评论(0) 推荐(0) 编辑

2015年3月11日

摘要: 使用事件探查器经常能捕捉到类似于execsp_execute10XXX,XXXX的RPC事件。我想问下从哪里可以看到存储过程sp_execute10的内容呢??方法如下:在新建的profiler的模板里面的EventData中勾选storeprocedure的SP:StmtStartingORSP:... 阅读全文
posted @ 2015-03-11 10:55 巴山游子 阅读(2966) 评论(0) 推荐(0) 编辑

2012年12月21日

摘要: HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。具体是如何进行加密,解密,验证的,且看下文。 阅读全文
posted @ 2012-12-21 22:05 巴山游子 阅读(234) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示