JVM堆内存

内存模型(HotSpot)

  1. 堆用来主要存放种类实例对象。
  2. 堆主要分为新生代(Young)与老年代(Old)。
  3. 新生代包含:Eden,From Survivor,To Survivor。
  4. 老年代主要用来保存程序声明周期长的对象。
  5. 永生代(Permanent):方法区,不属于java堆,另一个名字Non-Heap,指永久保存的区域,主要存放Class和Meta信息。

方法区回收

方法区回收的性价比比较低。在堆中,GC一次可以回收70%-95%空间,而永生代只能回收很少的空间。但也会执行回收,当内存严重不足时,会回收方法区的无用的常量和无用的类。

GC

MinorGC
  1. MinorGC发生在新生代,采用复制算法。
  2. Eden(包含一个survivor区域)对象初始化------>MinorGC------>如果在另一个Survivor有足够空间容纳对象,则通过复制算法把对象复制到Survivor并标记年龄为1------>清理Eden区域------>后续每次MinorGC,年龄都+1---->当到达阈值(default 15)这些对象就会晋升成为老年代。
  3. 如果是大对象,可能直接进入老年代。
FullGC(stop the world)
  1. FullGC发生在老年代,采用标记-消除或者标记-整理算法。
  2. 发生MinorGC前,先检查Old最大的可用连续空间>新生代所有对象之和,如果成立,则MinorGC安全,反之,会检查HandlePromotionFailure是否允许担保失败,若是,则检查Old最大可用连续空间>历次晋升到Old的对象的平均大小,如果成立,则尝试MinorGC.如果不允许担保失败,则转换为一次FullGC。
  3. 标记-清除算法和标记-整理算法会产生很多内存碎片,如果后续要分配一个大对象,没有足够多可用的连续空间,就会提前FullGC。

GC日志

添加vm参数:-XX:+PrintGCDetails

MinorGC

[GC [PSYoungGen: 1019K->568K(28672K)] 1019K->568K(92672K), 0.0529244 secs] [Times: user=0.00 sys=0.00, real=0.06 secs]
翻译: [GC [PSYoungGen{新生代} 1019K{MinorGC前新生代内存使用}->568K{MinorGC后新生代内存使用}(28672K{新生代总的内存大小}) 1019K{MinorGC前JVM堆内存使用的大小}->568K{MinorGC后JVM堆内存使用的大小}(92672K{堆的可用内存大小}), 0.0529244 secs{MinorGC总耗时}] [Times: user{用户耗时}=0.00 sys{系统耗时}=0.00, real{实际耗时}=0.06 secs]

FullGC

[Full GC [PSYoungGen: 568K->0K(28672K)] [ParOldGen: 0K->478K(64000K)] 568K->478K(92672K) [PSPermGen: 2484K->2483K(21504K)], 0.0178331 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
翻译: [Full GC [PSYoungGen: 568K->0K(28672K)] [ParOldGen{老年代}: 0K{FullGC前老年代内存使用}->478K{FullGC后老年代内存使用}(64000K{老年代总的内存大小})] 568K{FullGC前JVM堆内存使用的大小}->478K{FullGC后JVM堆内存使用的大小}(92672K{堆的可用内存大小}) [PSPermGen{永久代}: 2484K->2483K(21504K)], 0.0178331 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]

JVM参数

-XX:+<option> 启用选项
-XX:-<option>不启用选项
-XX:<option>=<number>
-XX:<option>=<string>

堆设置
  1. -Xms :初始堆大小
  2. -Xmx :最大堆大小
  3. -Xmn:新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%
  4. -XX:NewSize=n :设置年轻代大小
  5. -XX:NewRatio=n: 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
  6. -XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
  7. -XX:PermSize=n 永久代(方法区)的初始大小
  8. -XX:MaxPermSize=n :设置永久代大小
  9. -Xss 设定栈容量;对于HotSpot来说,虽然-Xoss参数(设置本地方法栈大小)存在,但实际上是无效的,因为在HotSpot中并不区分虚拟机和本地方法栈。
  10. -XX:PretenureSizeThreshold (该设置只对Serial和ParNew收集器生效) 可以设置进入老生代的大小限制
  11. -XX:MaxTenuringThreshold=1(默认15)垃圾最大年龄 如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率 该参数只有在串行GC时才有效.
收集器设置
  1. -XX:+UseSerialGC :设置串行收集器
  2. -XX:+UseParallelGC :设置并行收集器
  3. -XX:+UseParallelOldGC :设置并行年老代收集器
  4. -XX:+UseConcMarkSweepGC :设置并发收集器
垃圾回收统计信息
  1. -XX:+PrintHeapAtGC GC的heap详情
  2. -XX:+PrintGCDetails GC详情
  3. -XX:+PrintGCTimeStamps 打印GC时间信息
  4. -XX:+PrintTenuringDistribution 打印年龄信息等
  5. -XX:+HandlePromotionFailure 老年代分配担保(true or false)
  6. -Xloggc:gc.log 指定日志的位置
并行收集器设置
  1. -XX:ParallelGCThreads=n :设置并行收集器收集时使用的CPU数。并行收集线程数。
  2. -XX:MaxGCPauseMillis=n :设置并行收集最大暂停时间
  3. -XX:GCTimeRatio=n :设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
  1. -XX:+CMSIncrementalMode :设置为增量模式。适用于单CPU情况。
  2. -XX:ParallelGCThreads=n :设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
其他
  1. -XX:PermSize=10M和-XX:MaxPermSize=10M限制方法区大小。
  2. -XX:MaxDirectMemorySize=10M指定DirectMemory(直接内存)容量,如果不指定,则默认与JAVA堆最大值(-Xmx指定)一样。
  3. -XX:+HeapDumpOnOutOfMemoryError 可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照(.hprof文件)以便时候进行分析(比如Eclipse Memory Analysis)。

参考:https://blog.csdn.net/u013256816/article/details/50764532

猜你喜欢

转载自www.cnblogs.com/feichen-2018/p/9122115.html
今日推荐