zoukankan      html  css  js  c++  java
  • 有关Java内存溢出及内存消耗的小知识

    内存溢出原理: 
    我们知道,Java程序本身是不能直接在计算机上运行的,它需要依赖于硬件基础之上的操作系统和JVM(Java虚拟机)。 

    Java程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序。这个初始内存和最大内存在一定程度上会影响应用程序的性能。 

    JVM其实就是操作系统上的一个普通程序(进程名叫java,这个程序可以解释执行class文件,系统中当前运行了多少个java程序就会有多少个java进程)。 

    当Java进程启动时会首先分配一块堆内存(最小内存),以后每当java程序要求JVM(java进程)分配内存时,JVM就会在预先分配的那块内存上为java程序分配内存,当预先分配的那块内存用完时,JVM会再向操作系统要内存(物理内存),但是JVM不会无限制的向操作系统要内存,当它占用的实际内存达到一个预定值(最大可用内存)时,如果Java程序还向JVM要内存,并且JVM无法通过垃圾回收机制回收当前堆中的内存来为java程序服务时,它就会给程序抛出异常:java.lang.OutOfMemoryError。 
    其中内存回收时机并不是在用掉内存达到最大可用内存时才进行,它的运行时机是不确定的。可见JVM的最大可用内存就是java程序能够使用的最大内存。 
    例如: 
    我们把某JAVA程序的JVM最大可用内存设为200M,而我们的物理内存是1G。 
    这种情况下,我们的java程序最多能使用200M内存,虽然我们可能还有800M的内存可用,但是当我们的程序用掉200M后,如果再要内存,JVM不会因为我们还有800M的内存而为我们分配内存,它会抛出java.lang.OutOfMemoryError异常。 



    Runtime.getRuntime().totalMemory() :返回 Java 虚拟机中的内存总量。 
    Runtime.getRuntime().maxMemory()   :返回 Java 虚拟机试图使用的最大内存量。 
    Runtime.getRuntime().freeMemory()  :返回 Java 虚拟机中的空闲内存量。 
    单位是字节(Byte) 

    1024Byte(字节)=1KB 
    1024KB=1MB 
    1024MB=1GB 
    1024GB=1TB 


    Tomcat服务器的例子: 

    1.java.lang.OutOfMemoryError: PermGen space 

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space。从文字上看就是内存溢出,解决方法是加大内存。为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。 

    解决方法: 手动设置MaxPermSize大小 

    修改TOMCAT_HOME/bin/catalina.sh 
    在“echo "Using CATALINA_BASE:    $CATALINA_BASE"”上面加入以下行: 
    JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m 

    建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。 

    2.java.lang.OutOfMemoryError: Java heap space 

    JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置。JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。 

    解决方法:手动设置Heap size 

    修改TOMCAT_HOME/bin/catalina.sh 
    在“echo "Using CATALINA_BASE:    $CATALINA_BASE”“上面加入以下行: 
    JAVA_OPTS="-server -Xms800m -Xmx800m    -XX:MaxNewSize=256m" 

    提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 

    Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。有以下几种方法可以选用: 

    第一种方法: 
    Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增加如下设置: 
    JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】' 
    需要把这个两个参数值调大。例如: 
    JAVA_OPTS='-Xms256m -Xmx512m' 
    表示初始化内存为256MB,可以使用的最大内存为512MB。 


    第二种方法: 
    环境变量中设     变量名:JAVA_OPTS     变量值:-Xms512m   -Xmx512m 


    第三种方法: 
    前两种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的Tomcat等),但是有些安装版的Tomcat下没有catalina.bat,这个时候可以采用如下方法,当然这个方法也是最通用的方法:打开tomcatHome/in/ omcat5w.exe,点击Java选项卡,然后将会发现其中有这么两项:Initial memory pool和Maximum memory pool.Initial memory pool这个就是初始化设置的内存的大小。Maximum memory pool这个是最大内存的大小 设置完了就按确定然后再重启TOMCAT你就会发现tomcat中jvm可用的内存改变了 

    另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。 
    如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究 垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。 

    一个要注意的地方:建议把内存的最高值跟最低值的差值缩小,不然会浪费很多内存的, 最低值加大 ,最高值可以随便设,但是要根据实际的物理内存 ,如果内存设置太大了,比如设置了512M最大内存,但如果没有512M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的情况。 

  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/zhaogaojian/p/8120360.html
Copyright © 2011-2022 走看看