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 s tacks: 保存 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/
2. Garbage collection in the HotSpot JVM –
http://www-128.ibm.com/developerworks/java/library/j-jtp11253/
3. Tuning Garbage Collection with the 5.0 JavaTM Virtual Machine
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
4. Diagnosing a GC problem –
转载于:https://blog.51cto.com/lya041/680116