zoukankan      html  css  js  c++  java
  • 关于java的JVM和GC

    这篇文章写的很清楚:http://blog.csdn.net/winniepu/article/details/4829087

    1. Java堆中各代分布

     

    图1:Java堆中各代分布

    Young:主要是用来存放新生的对象。

    Old:主要存放应用程序中生命周期长的内存对象。

    Permanent:是指内存的永久保存区域,主要存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域. 它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

    2. JVM 使用的GC算法是什么?

    分代收集。

    即将内存分为几个区域,将不同生命周期的对象放在不同区域里;

    在GC收集的时候,频繁收集生命周期短的区域(Young area);

    比较少的收集生命周期比较长的区域(Old area);

    基本不收集的永久区(Perm area)。

    3. GC  Full GC 有什么区别?

    GC(或Minor GC):收集 生命周期短的区域(Young area)。

    Full GC (或Major GC):收集生命周期短的区域(Young area)和生命周期比较长的区域(Old area)。

    他们的收集算法不同,所以使用的时间也不同。 GC 效率也会比较高,我们要尽量减少 Full GC 的次数。 当显示调用System.gc() 时,gc does a full collection(both young generation and tenured generation).

    4. Minor GC后,Eden是空的吗?

    是的,Minor GC会把Eden中的所有活的对象都移到Survivor区域中,如果Survivor区中放不下,那么剩下的活的对象就被移到Old generation 中。

    5. Garbage collection options(JDK1.4)

     

    图2:GC参数

    堆设置 
    -Xms :初始堆大小 
    -Xmx :最大堆大小 
    -XX:NewSize=n :设置年轻代大小 
    -XX:NewRatio=n: 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4 
    -XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5 
    -XX:MaxPermSize=n :设置持久代大小 
    收集器设置 
    -XX:+UseSerialGC :设置串行收集器 
    -XX:+UseParallelGC :设置并行收集器 
    -XX:+UseParalledlOldGC :设置并行年老代收集器 
    -XX:+UseConcMarkSweepGC :设置并发收集器 
    垃圾回收统计信息 
    -XX:+PrintGC 
    -XX:+PrintGCDetails 
    -XX:+PrintGCTimeStamps 
    -Xloggc:filename 
    并行收集器设置 
    -XX:ParallelGCThreads=n :设置并行收集器收集时使用的CPU数。并行收集线程数。 
    -XX:MaxGCPauseMillis=n :设置并行收集最大暂停时间 
    -XX:GCTimeRatio=n :设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n) 
    并发收集器设置 
    -XX:+CMSIncrementalMode :设置为增量模式。适用于单CPU情况。 
    -XX:ParallelGCThreads=n :设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

    6. 例子:Heap size 设置

    场景:在JAVA_HOME下demo/jfc/SwingSet2/目录下执行下面的命令:

        java -jar -Xmn4m -Xms16m -Xmx16m SwingSet2.jar

    系统输出:

    Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space

    Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space

    Exception in thread "Image Fetcher 1" java.lang.OutOfMemoryError: Java heap space

    Exception in thread “Image Fetcher 2” java.lang.OutOfMemoryError: Java heap space

    调优:将-Xms和-Xmx选项设置为32m,而-Xmn为1/4的-Xmx值。

    结果:执行java -jar –Xmn8m –Xms32m -Xmx32m SwingSet2.jar,系统正常运行。

    7. JVM  Runtime Data Area(运行时数据区):

     

    图3:JVM运行时数据区(一)

    Heap: JVM只有一个为所有线程所共享的堆,所有的类实例和数组都是在堆中创建的。

    Method area: JVM只有一个为所有的线程所共享的方法区。它存储类结构,例如运行时常量池,成员和方法数据以及方法、构造方法的代码。

    Java Stacks: 每个JVM线程拥有一个私有的栈。

    Pc registers: JVM可以同时支持运行多个线程,因此每个线程需要各自的PC(program counter)寄存器。

    Native method stacks: 保存native方法进入区域的地址 。

     

    图4:JVM运行时数据区(二)

    Heap和Method area被所有线程共享,其生存期和JVM的生存期相同;Java Stacks、Pc registers、Native method stacks被每个线程独自拥有,其生存期和线程的生存期相同。

     

    8. 常见的内存泄露错误

    很多开发人员都碰到过java.lang.OutOfMemoryError的错误。这种错误又分两种:java.lang.OutOfMemoryError: Java heap space和java.lang.OutOfMemoryError: PermGen space。引起这种错误的原因可能是程序问题,也可能是是JVM参数配置问题引起的。若是参数问题,前者可以同过配置-Xms和-Xmx参数来设置,而后者可以通过配置 -XX:PermSize和-XX:MaxPermSize来设置。

                                

    9 参考资料:

    1.  A brief history of garbage collection –

    http://www-128.ibm.com/developerworks/java/library/j-jtp10283/

    1. Garbage collection in the HotSpot JVM –

    http://www-128.ibm.com/developerworks/java/library/j-jtp11253/

    1. Tuning Garbage Collection with the 5.0 JavaTM Virtual Machine

    http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

    1. Diagnosing a GC problem –

    http://java.sun.com/docs/hotspot/gc1.4.2/example.html


    可以结合下面的理解一下

    主要通过以下的几个jvm参数来设置堆内存的:

    -Xmx512m 最大总堆内存,一般设置为物理内存的1/4
    -Xms512m 初始总堆内存,一般将它设置的和最大堆内存一样大,这样就不需要根据当前堆使用情况而调整堆的大小了
    -Xmn192m 年轻带堆内存,sun官方推荐为整个堆的3/8
    堆内存的组成 总堆内存 = 年轻带堆内存 + 年老带堆内存 + 持久带堆内存
    年轻带堆内存 对象刚创建出来时放在这里
    年老带堆内存 对象在被真正会回收之前会先放在这里
    持久带堆内存 class文件,元数据等放在这里
    -XX:PermSize=128m 持久带堆的初始大小
    -XX:MaxPermSize=128m 持久带堆的最大大小,eclipse默认为256m。如果要编译jdk这种,一定要把这个设的很大,因为它的类太多了。
  • 相关阅读:
    2017-5-21 Asp.Net内置对象 和 DropDownList时间年月日的三级联动
    【2017-04--28】Winform中ListView控件
    【2017-04-27】布局及容器控件、打开多窗体、构造函数传值、打开唯一窗口
    【2017-04-25】winform公共控件、菜单和工具栏
    【2017-04-24】WinForm基础、登录窗口、窗口属性
    【2017-04-20】Sql字符串注入式攻击与防御,实体类,数据访问类
    【2017-04-18】Ado.Net C#连接数据库进行增、删、改、查
    【2017-04-17】类库、通用变量、is和as、委托
    【2017-04-16】抽象类、接口、构造函数、重载、静态成员和方法
    【面向对象】类、访问修饰符、封装、继承、多态
  • 原文地址:https://www.cnblogs.com/latter/p/6402545.html
Copyright © 2011-2022 走看看