zoukankan      html  css  js  c++  java
  • JVM配置入门(有些乱,待整)

    it's better to add below lines into eclipse.ini

         -vm

        <Your JDK installed path>injavaw.exe

        -vmargs

        -Dosgi.requiredJavaVersion=1.6

        -Xms512m

        -Xmx1024m

        -XX:PermSize=512M

        -XX:MaxPermSize=1024M

        -Djava.net.preferIPv4Stack=true

    即jvm arguments

    -Xms512m      表示JVM初始分配的堆内存大小为512m(JVM Heap(堆内存)最小尺寸512MB,初始分配)

    -Xmx1024m    JVM最大允许分配的堆内存大小为1024m,按需分配(JVM Heap(堆内存)最大允许的尺寸256MB,按需分配)

    -XX:PermSize=512M          JVM初始分配的非堆内存

    -XX:MaxPermSize=1024M   JVM最大允许分配的非堆内存,按需分配

    PermSize和MaxPermSize 为java对象分配的内存(java永久生成对象permanent generation,如class对象,方法对象),这些内存不包括在heap(堆内存中)

    1)堆(Heap)和非堆(Non-heap)内存

            按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。
            可以看出JVM主要管理两种类型的内存:堆和非堆。

            简单来说堆就是Java代码可及的内存,是留给开发人员使用的;

            非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

            堆内存分配

         JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64;

                JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。

                默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;

                空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。

                因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC 后调整堆的大小。  

                说明:如果-Xmx 不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。 

        非堆内存分配

               JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;

               由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

             (还有一说:MaxPermSize缺省值和-server -client选项相关,

                -server选项下默认MaxPermSize为64m,

                -client选项下默认MaxPermSize为32m。这个我没有实验。)  

               XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 就是内存益出。 

               为什么会内存益出: 

              (1)这一部分内存用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同。 

              (2)GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。  

                     这种错误常见在web服务器对JSP进行pre compile的时候。  

    2)JVM内存限制(最大值)

     首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,  这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

    2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动,而有些机器无法启动?  通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种:堆内存和非堆内存,另外JVM最大内存首先取决于实际的物理内存和操作系统。所以说设置VM参数导致程序无法启动主要有以下几种原因: 1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize; 2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理内存这里需要说明一点的是,  如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

    3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置?  那为什么同样的参数在快捷方式或者命令行中有效而在eclipse.ini文件中是无效的呢?这是因为我们没有遵守eclipse.ini文件的设置规则: 参数形如“项 值”这种形式,中间有空格的需要换行书写,如果值中有空格的需要用双引号包括起来。比如我们使用-vm C:/Java/jre1.6.0/bin/javaw.exe参数设置虚拟机, 在eclipse.ini文件中要写成这样: -vm  C:/Java/jre1.6.0/bin/javaw.exe  -vmargs  -Xms128M  -Xmx512M  -XX:PermSize=64M  -XX:MaxPermSize=128M  实际运行的结果可以通过Eclipse中“Help”-“About Eclipse SDK”窗口里面的“Configuration Details”按钮进行查看。 另外需要说明的是,Eclipse压缩包中自带的eclipse.ini文件内容是这样的: -showsplash  org.eclipse.platform  --launcher.XXMaxPermSize  256m  -vmargs  -Xms40m  -Xmx256m  其中–launcher.XXMaxPermSize(注意最前面是两个连接线)跟-XX:MaxPermSize参数的含义基本是一样的,我觉得唯一的区别就是前者是eclipse.exe启动的时候设置的参数, 而后者是eclipse所使用的JVM中的参数。其实二者设置一个就可以了,所以这里可以把–launcher.XXMaxPermSize和下一行使用#注释掉。

    4. 其他的启动参数。 如果你有一个双核的CPU,也许可以尝试这个参数: -XX:+UseParallelGC 让GC可以更快的执行。(只是JDK 5里对GC新增加的参数)

    补充:   如果你的WEB APP下都用了大量的第三方jar,其大小超过了服务器jvm默认的大小,那么就会产生内存益出问题了。 解决方法: 设置MaxPermSize大小  可以在myelipse里选中相应的服务器比如tomcat5,展开里面的JDK子项页面,来增加服务器启动的JVM参数设置: -Xms128m  -Xmx256m  -XX:PermSize=128M  -XX:MaxNewSize=256m  -XX:MaxPermSize=256m 或者手动设置MaxPermSize大小,比如tomcat, 修改TOMCAT_HOME/bin/catalina.bat,在echo "Using CATALINA_BASE: $CATALINA_BASE"上面加入以下行:  JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m

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

    附:jvm server client

         看看你下面的这两个文件,是不是尺寸差别很大?
      %JAVA_HOME%/jre/bin/client/jvm.dll
      %JAVA_HOME%/jre/bin/server/jvm.dll
         Jvm动态库有client和server两个版本,分别针对桌面应用和服务器应用做了相应的优化,client版本加 载速度较快,server版本加载速度较慢但运行起来较快。
         让Tomcat 使用Server版本的jvm吧  在开始菜单 tomcat5 ->tomcat config的java属性中 有一项 jvm路径 指向server目录下的jvm就行了。
         启动速度对比一下,在我的C4.17 512M 的机器上client 版本一般在8s-16s内启动完成 server版本 在21s-26s左右启动完成。

         更改默认java.exe调用的jvm.dll,这个由jvm.cfg决定。
         编辑%JAVA_HOME%jrelibi386jvm.cfg  
         里面第一行写的是 -client 默认就是client版本 ,把第二行的-server KNOWN 放到第一行, 如下面所示
         -server KNOWN
         -client KNOWN
         -hotspot ALIASED_TO -client
         -classic WARN
         -native ERROR
         -green ERROR 
         改完保存,然后看看默认版本:
         C:java -version
         java version "1.4.2_07"
         Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_07-b05)
         Java HotSpot(TM) Server VM (build 1.4.2_07-b05, mixed mode)
          看到没有 Server VM 字样?是不是很酷啊!,小心机器不够快,启动等得你疯掉 :)

         ================================================================================

         几个基本概念:

              PermGen space:全称是Permanent Generation space,即永久代。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域,GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

               Heap space:存放Instance。

               Java Heap分为3个区,Young即新生代,Old即老生代和Permanent。

               Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象。

         几个参数设置的意义:

            xms/xmx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;

                            mx为最大可占用的YOUNG+OLD内存大小。

            在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

            NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;

                          MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

             PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;

                          MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

             SurvivorRatio:设置YOUNG代中Survivor空间和Eden空间的比例

    申请一块内存的过程:

    A. JVM会试图为相关Java对象在Eden中初始化一块内存区域

    B. 当Eden空间足够时,内存申请结束。否则到下一步

    C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区/OLD区 

    D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区

    E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

    F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

    我们的一种resin服务器的jvm参数设置:

    “-Xmx2000M -Xms2000M -Xmn500M -XX:PermSize=250M -XX:MaxPermSize=250M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log”

    是一种典型的响应时间优先型的配置。

    Java中有四种不同的回收算法,对应的启动参数为

    –XX:+UseSerialGC

    –XX:+UseParallelGC

    –XX:+UseParallelOldGC

    –XX:+UseConcMarkSweepGC

    1. Serial Collector

    大部分平台或者强制 java -client 默认会使用这种。

    young generation算法 = serial

    old generation算法 = serial (mark-sweep-compact)

    这种方法的缺点很明显,stop-the-world, 速度慢。服务器应用不推荐使用。

    2. Parallel Collector

    在linux x64上默认是这种,其他平台要加 java -server 参数才会默认选用这种。

    young = parallel,多个thread同时copy

    old = mark-sweep-compact = 1

    优点:新生代回收更快。因为系统大部分时间做的gc都是新生代的,这样提高了throughput(cpu用于非gc时间)

    缺点:当运行在8G/16G server上old generation live object太多时候pause time过长

    3. Parallel Compact Collector (ParallelOld)

    young = parallel = 2

    old = parallel,分成多个独立的单元,如果单元中live object少则回收,多则跳过

    优点:old old generation上性能较 parallel 方式有提高

    缺点:大部分server系统old generation内存占用会达到60%-80%, 没有那么多理想的单元live object很少方便迅速回收,同时compact方面开销比起parallel并没明显减少。

    4. Concurent Mark-Sweep(CMS) Collector

    young generation = parallel collector = 2

    old = cms

    同时不做 compact 操作。

    优点:pause time会降低, pause敏感但CPU有空闲的场景需要建议使用策略4.

    缺点:cpu占用过多,cpu密集型服务器不适合。另外碎片太多,每个object的存储都要通过链表连续跳n个地方,空间浪费问题也会增大。

    内存监控的方法:

    1.  jmap -heap pid        

    查看java 堆(heap)使用情况        

    using thread-local object allocation.        

    Parallel GC with 4 thread(s)          //GC 方式

     Heap Configuration:       //堆内存初始化配置         

    MinHeapFreeRatio=40     //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)         

    MaxHeapFreeRatio=70  //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)         

    MaxHeapSize=512.0MB  //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小         

    NewSize  = 1.0MB          //对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小         

    MaxNewSize =4095MB   //对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小         

    OldSize  = 4.0MB            //对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小         

    NewRatio  = 8         //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率         

    SurvivorRatio = 8    //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值          

    PermSize= 16.0MB       //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小          

    MaxPermSize=64.0MB  //对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小          

    Heap Usage:               //堆内存分步          

    PS Young Generation          

    Eden Space:          //Eden区内存分布            

    capacity = 20381696 (19.4375MB)  //Eden区总容量            

    used     = 20370032 (19.426376342773438MB)  //Eden区已使用            

    free     = 11664 (0.0111236572265625MB)  //Eden区剩余容量            

    99.94277218147106% used  //Eden区使用比率         

    From Space:        //其中一个Survivor区的内存分布             

    capacity = 8519680 (8.125MB)             

    used     = 32768 (0.03125MB)             

    free     = 8486912 (8.09375MB)             

    0.38461538461538464% used        

    To Space:            //另一个Survivor区的内存分布            

    capacity = 9306112 (8.875MB)            

    used     = 0 (0.0MB)            

    free     = 9306112 (8.875MB)            

    0.0% used        

    PS Old Generation  //当前的Old区内存分布            

    capacity = 366280704 (349.3125MB)            

    used     = 322179848 (307.25464630126953MB)            

    free     = 44100856 (42.05785369873047MB)            

    87.95982001825573% used        

    PS Perm Generation  //当前的 “永生代” 内存分布            

    capacity = 32243712 (30.75MB)            

    used     = 28918584 (27.57891082763672MB)            

    free     = 3325128 (3.1710891723632812MB)            

    89.68751488662348% used

  • 相关阅读:
    Elasticsearch聚合 之 Date Histogram聚合
    Elasticsearch聚合 之 Terms
    Elasticsearch分析聚合
    mysql-聚合函数
    flask学习笔记(-操作数据库)
    在VS中调试javascript脚本
    jquery获取设置input值
    jquery后加Dom绑定事件
    Juicer——a fast template engine
    ASP.NET 一般处理程序
  • 原文地址:https://www.cnblogs.com/specification/p/3507651.html
Copyright © 2011-2022 走看看