• OOM三种情况


    第一种OutOfMemoryError: PermGen space
    发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关

           解决这类问题有以下两种办法:

        1. 增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小

    其中XX:PermSize是初始永久保存区域大 小,

    XX:MaxPermSize是最大永久保存区域大小。

    如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

    如果是windows服务器还可以在系统环境变量中设置。

    感觉用tomcat发布sprint+struts+hibernate架构的程序时很容易发生这种内存溢出错误。使用上述方法,我成功解决了部署ssh项目的tomcat服务器经常宕机的问题。

        2.清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到 tomcat共同的lib下,减少类的重复加载。这种方法是网上部分人推荐的,我没试过,但感觉减少不了太大的空间,最靠谱的还是第一种方法。

    第二种OutOfMemoryError: ?Java heap space
    发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关

    解决这类问题有两种思路:


    1.检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。 我以前写一个使用K-Means文本聚类算法对几万条文本记录(每条记录的特征向量大约10来个)进行文本聚类时,由于程序细节上有问题,就导致了 Java heap space的内存溢出问题,后来通过修改程序得到了解决。


    2.增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m


    第三种OutOfMemoryError:unable to create new native thread
    在java应用中,有时候会出现这样的错误:OutOfMemoryError: unable to create new native thread.这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下, 你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。
    那么是什么原因造成这种问题呢?
    每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这 500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内 存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理 线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程, 因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。
    这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。
    给出一个有关能够创建线程的最大个数的估算公式:
    (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) 对于jdk1.5而言,假设操作系统保留120M内存:
    1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380对于栈大小为256KB的jdk1.4而言,
    1.5GB allocated to JVM: ~1520 threads
    1.0GB allocated to JVM: ~3520 threads?对于这个异常我们首先需要判断下,发生内存溢出时进程中到底都有什么样的线程,这些线程是否是应该存在的,是否可以通过优化来降低线程数; 另外一方面默认情况下java为每个线程分配的栈内存大小是1M,通常情况下,这1M的栈内存空间是足足够用了,因为在通常在栈上存放的只是基础类型的数 据或者对象的引用,这些东西都不会占据太大的内存, 我们可以通过调整jvm参数,降低为每个线程分配的栈内存大小来解决问题,例如在jvm参数中添加-Xss128k

  • 相关阅读:
    Android开发进阶 -- 通用适配器 CommonAdapter
    如何巧妙地在基于 TCP Socket 的应用中实现用户注册功能?
    如何让基于.NET 2.0的应用在高版本的系统上运行?
    即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】
    即时通信系统中实现聊天消息加密,让通信更安全【低调赠送:C#开源即时通讯系统(支持广域网)——GGTalk4.5 最新源码】
    程序员的那些事儿 -- 高级程序员买衣服
    程序员的那些事儿 -- 皆大欢喜的加薪
    GGTalk即时通讯系统(支持广域网)终于有移动端了!(技术原理、实现、源码)
    如何做到在虚拟数据库和真实数据库之间自由切换?【低调赠送:QQ高仿版GG 4.4 最新源码】
    如何实现:录制视频聊天的全过程? 【低调赠送:QQ高仿版GG 4.3 最新源码】
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/10558924.html
Copyright © 2020-2023  润新知