JVM调优篇-06
1.JVM 运行时 GC 相关的参数
-Xms4096m //初始堆大小
-Xmx4096m //最大堆大小
-Xmn1536m //新生代大小 eden + from + to
-Xss512K //线程大小
-XX:NewRatio=2 //新生代和老年代的比例
-XX:MaxPermSize=64m //持久代最大值
-XX:PermSize=16m //持久代初始值
-XX:SurvivorRatio=8 // eden 区和survivor区的比例
-verbose:gc
-Xloggc:gc.log //输出gc日志文件
-XX:+UseGCLogFileRotation //使用log文件循环输出
-XX:NumberOfGCLogFiles=1 //循环输出文件数量
-XX:GCLogFileSize=8k //日志文件大小限制
-XX:+PrintGCDateStamps //gc日志打印时间
-XX:+PrintTenuringDistribution //查看每次minor GC后新的存活周期的阈值
-XX:+PrintGCDetails //输出gc明细
-XX:+PrintGCApplicationStoppedTime //输出gc造成应用停顿的时间
-XX:+PrintReferenceGC //输出堆内对象引用收集时间
-XX:+PrintHeapAtGC //输出gc前后堆占用情况
-XX:+UseParallelGC //年轻代并行GC,标记-清除
-XX:+UseParallelOldGC //老年代并行GC,标记-清除
-XX:ParallelGCThreads=23 //并行GC线程数, cpu<=8?cpu:5*cpu/8+3
-XX:+UseAdaptiveSizePolicy //默认,自动调整年轻代各区大小及晋升年龄
-XX:MaxGCPauseMillis=15 //每次GC最大停顿时间,单位为毫秒
-XX:+UseParNewGC //Serial多线程版
-XX:+UseConcMarkSweepGC //CMS old gc
-XX:+UseCMSCompactAtFullCollection //FullGC后进行内存碎片整理压缩
-XX:CMSFullGCsBeforeCompaction=n //n次FullGC后执行内存整理
-XX:+CMSParallelRemarkEnabled //启用并行重新标记,只适用ParNewGC
-XX:CMSInitiatingOccupancyFraction=80 //cms作为垃圾回收是,回收比例80%
-XX:ParallelGCThreads=23 //并行GC线程数,cpu<=8?cpu:5*cpu/8+3
-XX:-UseSerialGC //默认不启用,client使用时启用
-XX:+UseG1GC //启用G1收集器
-XX:-UseAdaptiveSizePolicy //默认,不自动调整各区大小及晋升年龄
-XX:PretenureSizeThreshold=2097152 //直接晋升到老年代的对象大小
-XX:MaxTenuringThreshold=15(default) //晋升到老年代的对象年龄,PSGen无效
-XX:-DisableExplicitGC //禁止在运行期显式地调用?System.gc()
-XX:+HeapDumpOnOutOfMemoryError //在OOM时输出堆内存快照
-XX:HeapDumpPath=./java_pid<pid>.hprof //堆内存快照的存储路径
-XX:+CMSScavengeBeforeRemark //执行CMS重新标记之前,尝试执行一此MinorGC
-XX:+CMSPermGenSweepingEnabled //开启永久代的并发垃圾收集
2.触发 GC 的类型?
Java 虚拟机会把每次触发 GC 的信息打印出来,可以根据日志来分析触发 GC 的原因。
- GC_FOR_MALLOC:表示是在堆上分配对象时内存不足触发的 GC。
- GC_CONCURRENT:当我们应用程序的堆内存达到一定量,或者可以理解为快要满的时候,系统会自动触发 GC 操作来释放内存。
- GC_EXPLICIT:表示是应用程序调用 System.gc、VMRuntime.gc 接口或者收到 SIGUSR1 信号时触发的 GC。
- GC_BEFORE_OOM:表示是在准备抛 OOM 异常之前进行的最后努力而触发的 GC。
3.查看当前使用的垃圾收集器?
java -XX:+PrintCommandLineFlags -version
4.垃圾收集器比较?
5.Minor GC 与 Full GC
-
新生代 GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
-
老年代 GC(Major GC / Full GC):指发生在老年代的垃圾收集动作,出现了 Major GC,经常会伴随至少一次 Minor GC(非绝对),MajorGC 的速度一般会比 Minor GC 慢 10 倍以上。
-
Minor GC 与 Full GC 触发条件:
-
当 Eden 区没有足够的空间进行分配时
-
老年代最大可用连续空间大于Minor GC 历次晋升到老年代对象的平均大小
-
-
Full GC 触发条件:
-
调用 System.gc()时(系统建议执行 Full GC,但是不必然执行)
-
老年代空间不足时
-
方法区空间不足时
-
老年代最大可用连续空间小于Minor GC 历次晋升到老年代对象的平均大小
-
CMS GC 在垃圾回收的时候,当对象从 Eden 区进入 Survivor 区,Survivor 区空间不足需要放入老年代,而老年代空间也不足时
-
6.为什么 GC 分代年龄为 15?
因为对象头中的 Mark Word 采用 4 个 bit 位来保存年龄,4 个 bit 位能表示的最大数就是 15
对象头包含两类信息:
一种是 Mark Word:
用于存储对象自身的运行时数据,如 HashCode,GC 的分代年龄,锁状态标志,线程持有的锁,偏向线程 ID,偏向时间戳等。这部数据的长度在 32 位和 64 位的虚拟机中分别为 32 比特和 64 比特。(Mark Word 的 32 个比特存储空间中的 25 个比特用于存储对象的 HashCode,4 个比特存储对象分代年龄,2 个比特存储锁标志位,一个比特固定为 0)
另一种是 Klass Pointer 类型指针:
即对象指向它的类型元数据的指针,Java 通过这个指针确定该对象是哪个类的实例。但是并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息不一定要经过对象本身。
MetaSpace 主要由 Klass Metaspace 和 NoKlass Metaspace 两大部分组成。
- Klass MetaSpace: 就是用来存 Klass 的,就是 Class 文件在 JVM 里的运行时数据结构,这部分默认放在 Compressed Class Pointer Space 中,是一块连续的内存区域,紧接着 Heap。Compressed Class Pointer Space 不是必须有的,如果设置了
-XX:-UseCompressedClassPointers
,或者-Xmx
设置大于 32 G,就不会有这块内存,这种情况下 Klass 都会存在 NoKlass Metaspace 里。 - NoKlass MetaSpace: 专门来存 Klass 相关的其他的内容,比如 Method,ConstantPool 等,可以由多块不连续的内存组成。虽然叫做 NoKlass Metaspace,但是也其实可以存 Klass 的内容.
7.说说 ZGC?
- 在尽可能对吞吐量影响不大的前提下,实现在任意堆内存大小下都可以把垃圾收集的停颇时间限制在十毫秒以内的低延迟。
- ZGC 收集器是一款基于 Region 内存布局的,(暂时)不设分代的,使用了读屏障、染色指针和内存多重映射等技术来实现可并发的标记-压缩算法的,以低延迟为首要目标的一款垃圾收集器。
- ZGC 的工作过程可以分为 4 个阶段:并发标记 - 并发预备重分配 - 并发重分配 - 并发重映射等。
- ZGC 几乎在所有地方并发执行的,除了初始标记的是 STW 的。所以停顿时间几乎就耗费在初始标记上,这部分的实际时间是非常少的。
- 点赞
- 收藏
- 关注作者
评论(0)