zoukankan      html  css  js  c++  java
  • 服务器内存溢出问题

    系统测试时,导出、下载功能,偶尔会出现“out of memory”(内存溢出)问题。

    内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。

       引起内存溢出的原因有很多种,常见的有以下几种:
      1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
      2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
      3.代码中存在死循环或循环产生过多重复的对象实体;
      4.使用的第三方软件中的BUG;
      5.启动参数内存值设定的过小;

    内存溢出的解决方案
          第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)

      第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。

      第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

    重点排查以下几点:
      1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
      2.检查代码中是否有死循环或递归调用。 

      3.检查是否有大循环重复产生新对象实体。 

      4.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中   数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。 

      5.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

      第四步,使用内存查看工具动态查看内存使用情况

    如何解决内存溢出的问题,接下来以tomcat服务器为例:

    我们首先得找到内存管理所要设置的参数在哪个文件:<CATALINA_HOME>/bin/catalina.bat。

    需要添加一行代码:

    JAVA_OPTS="-Xms512m-Xmx512m -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=256m"

    下面分别对各参数进行介绍和解释:

    JVM 相关参数:

    参数名参数说明

    -server 启用能够执行优化的编译器, 显著提高服务器的性能,但使用能够执行优化的编译器时,服务器的预备时间将会较长。生产环境的服务器强烈推荐设置此参数。

    -Xss 单个线程堆栈大小值;JDK5.0 以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

    -XX:+UseParNewGC 可用来设置年轻代为并发收集【多CPU】,如果你的服务器有多个CPU,你可以开启此参数;开启此参数,多个CPU 可并发进行垃圾回收,可提高垃圾回收的速度。此参数和+UseParallelGC,-XX:ParallelGCThreads搭配使用。

    +UseParallelGC 选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。可提高系统的吞吐量。

    -XX:ParallelGCThreads 年轻代并行垃圾收集的前提下(对并发也有效果)的线程数,增加并行度,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。永久存储区相关参数:参数名参数说明

    -Xnoclassgc 每次永久存储区满了后一般GC 算法在做扩展分配内存前都会触发一次FULL GC,除非设置了-Xnoclassgc.

    -XX:PermSize 应用服务器启动时,永久存储区的初始内存大

    -XX:MaxPermSize 应用运行中,永久存储区的极限值。为了不消耗扩大JVM 永久存储区分配的开销,将此参数和-XX:PermSize这个两个值设为相等。堆空间相关参数参数名参数说明

    -Xms 启动应用时,JVM 堆空间的初始大小值。

    -Xmx 应用运行中,JVM 堆空间的极限值。为了不消耗扩大JVM 堆控件分配的开销,将此参数和-Xms 这个两个值设为相等,考虑到需要开线程,讲此值设置为总内存的80%.

    -Xmn 此参数硬性规定堆空间的新生代空间大小,推荐设为堆空间大小的1/4。

    上面所列的JVM 参数关系到系统的性能,而其中-XX:PermSize,

    -XX:MaxPermSize,-Xms,-Xmx 和-Xmn 这5 个参数更是直接关系到系统的性能,系统是否会出现内存溢出。

    -XX:PermSize 和-XX:MaxPermSize 分别设置应用服务器启动时,永久存储区的初始大小和极限大小;在生成环境中强烈推荐将这个两个值设置为相同的值,以避免分配永久存储区的开销,具体的值可取系统“疲劳测试”获取到的永久存储区的极限值;如果不进行设置-XX:MaxPermSize 默认值为64M,一般来说系统的类定义文件大小都会超过这个默认值。

    -Xms 和-Xmx 分别是服务器启动时,堆空间的初始大小和极限值。-Xms的默认值是物理内存的1/64 但小于1G,-Xmx 的默认值是物理内存的1/4 但小于1G.在生产环境中这些默认值是肯定不能满足我们的需要的。也就是你的服务器有8g 的内存,不对JVM 参数进行设置优化,应用服务器启动时还是按默认值来分配和约束JVM 对内存资源的使用,不会充分的利用所有的内存资源。

    结论:“永久存储区溢出(java.lang.OutOfMemoryError:Java Permanent Space)”乃是永久存储区设置太小,不能满足系统需要的大小,此时只需要调整-XX:PermSize 和-XX:MaxPermSize 这两个参数即可。“JVM 堆空间溢出(java.lang.OutOfMemoryError: Java heap space)”错误是JVM 堆空间不足,此时只需要调整-Xms 和-Xmx 这两个参数即可。

  • 相关阅读:
    [转贴] 2016一月12日起.NET 4, 4.5 and 4.5.1 停止安全更新、技术支持 or hotfix
    Windows Azure 入门 -- VS 2015部署 ASP.NET网站(项目) 与 数据库
    [职场]工作多久才能换工作?下一个工作年薪该多高?
    [转贴] ASP.NET -- Web Service (.asmx) & JSON
    ADO.NET #3-1 (GridView + DataReader + SqlCommand)完全手写Code Behind
    File 与 Log #3--动态加入控件,[图片版]访客计数器(用.txt档案来记录)
    小图示优化
    GridView的 PreRender事件与范例--GridView + CheckBox,点选多列资料(复选删除)
    [习题] FindControl 简单练习--GridView + CheckBox,点选多列数据(复选删除)#3 List或数组
    GridView的 PreRender事件与 RowCreated、RowDataBound事件大乱斗
  • 原文地址:https://www.cnblogs.com/String-song/p/14536817.html
Copyright © 2011-2022 走看看