zoukankan      html  css  js  c++  java
  • 关于hibernate导致tomcat内存暴涨,页面反应速度减慢

    2012年6月23日

    今天追踪一个关于页面内存暴涨,页面响应过慢的问题。花了4个多小时,总算找到问题出在哪了。

    一、问题描述

    最近我们在一台独享服务器上搭建了Tomcat6.0.19环境,发现访问首页时,内存暴涨,一直不退。每次刷新内存增加近10M。一个人狂刷新一分钟就可以把tomcat搞死机。

    然后,找各种办法解决问题。整了几天,每天中午轮流监控Tomcat服务器,发现它挂了后就重启。累坏了。

    每天到google上面搜索答案,有人说是程序的问题,程序内存泄露。甚至问到“有没有数据库没有释放”、“有没有使用死循环”、有没有写“System.gc()自动释放内存”、有没有“在Service层查询时使用all()方法,查处了所有记录”。等等。

    而我一直不承认程序有问题。理由是:我们曾经将这个程序在租用的2个虚拟主机中用了近1个月。不断维护,最后达到一个星期没有出现一个异常的情况。

    二、问题分析(关于tomcat内存溢出问题)

    分析Tomcat死机的日志,发现是内存耗尽。

    大致有这么一段,PSPermGen total   86016K   used 86015K   

    到网上搜了一下,明白了jvm内存分类。然后配置内存,让tomcat自动回收jvm内存。

    当然,配置过程也遇到了很多问题,花了一天多。问题是网上的很多人都是抄来抄去,要在一大堆垃圾中选出精品不容易呀。

    配了一天都只起到一定作用。比如:给tomcat设置较大内存后,tomcat可以承受到2.19G。只是再刷新就可以把他整崩溃。

    最后,请了几个牛人帮忙,一个牛人凌晨帮我们看tomcat配置。问我们,是否加了,-server参数。最后,我同事加上了-server参数。 然后,回去睡觉了,发现java.exe内存真的能回收了。很多问题也解决了。

    我们配置如下:(将tomcat6的安装版卸载,换成绿色版)

    在catalina.bat的@echo off下面添加(就是第二行)

    set JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=256m 

    在startup.bat下面添加(让tomcat的工具自动回收内存)

    @echo off
    set JAVA_OPTS=%JAVA_OPTS%
    -Dcom.sun.management.jmxremote.port=1090
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
    -Djava.util.logging.config.file="%CATALINA_HOME%\conf\logging.properties"

    三、问题分析(关于页面反应速度异常)

    我们的首页显示餐馆的信息,主要根据用户选择地区,然后将该地区的餐馆列表和热卖美食列表显示出来。我们发现一个很奇怪的现象,访问某一学校东校区时:

    8个餐馆:Action执行2063ms(获取餐馆列表:1220ms + 获取热卖美食:825ms)。

    然后换成其他校区分别为:

    3个餐馆:Action执行 51ms   (获取餐馆列表:29    +    获取热卖美食: 2)

    3个餐馆:Action执行 53ms   (32   + 1)

    4个餐馆:Action执行 90ms   (74    + 1)

    看到这个数据,我就很纳闷,怎么时间不成比例呢?

    于是,我将8个餐馆删掉4个对比。由于有外键关联,我必须要删除其他的很多的。为了删除一个餐馆记录,我必须删除其他记录多达6个表处,可见外键关系较为复杂。

    等我删掉后,发现东校区:

    4个餐馆:Action执行111ms(获取餐馆列表:53ms + 获取热卖美食:37ms)。

    我发现这个变化太明显了吧。然后,我怀疑那四个餐馆关联了太多东西。我查询出来的不仅仅是餐馆,可能连带查询了另外的6个表的记录。

    我就想到了是hbm.xml文件中设置lazy = "true"问题。

    通过测试,我发现是 餐馆对应订单时,one-to-many时,lazy = "true"。这个就很明显了。

    查询一个餐馆,就把它的上百份订单级联查询出来了,同时把所有菜品也级联查询出来了,把所有菜品分类都查询出来了。

    而就东校区的这8家餐馆订单较多,其他校区由于刚开业,订单几乎没有。这下就可以解释为什么东校区这么耗时间(当然也耗内存)。

    然后,我将hbm.xml的所有lazy="true"全部去掉,恢复数据库数据。

    东校区结果如下:

    8个餐馆:Action执行25ms(获取餐馆列表:3ms + 获取热卖美食:8ms)。

    四、结论:

            lazy="false"使用时要慎重。例如:对与1:1的情况,使用直接影响不大,对于1:n情况就要慎重了。尤其是n成百上千时,问题就相当严重了。我建议最好不用。

    第一次,配置和管理服务器,收获真大呀。对我以后的编程风格都造成了深远的影响。我会注意服务器的时间和空间效率问题。

    当然测试方法比较土。先将服务器正常上线后,我会学着使用JMeter和roadrunner的工具做压力测试,配置好服务器。

    忙里偷闲!记录下来!

  • 相关阅读:
    @Autowired 与@Resource的区别(详细)
    mvn clean compile package install deploy
    Android Studio 之 NDK篇
    cmake处理多源文件目录的方法
    linux CMakeLists.txt 语法
    在 Android Studio 2.2 中愉快地使用 C/C++
    MySql 模糊查询
    C++静态库与动态库详解
    配置Yum源repo文件及搭建本地Yum服务器
    yum命令
  • 原文地址:https://www.cnblogs.com/pyrmkj/p/2559375.html
Copyright © 2011-2022 走看看