JVM三大性能调优参数

JVM 几个重要的参数:
-server -Xmx3g -Xms3g -XX:MaxPermSize=128m
-XX:NewRatio=1 新生代(Eden + 2*S)与老年代(不包括永久区)的比值
-XX:SurvivorRatio=8 2个Survivor区和Eden区的比值
-XX:+UseParallelGC
-XX:ParallelGCThreads=8
-XX:+UseParallelOldGC 这个是JAVA 6出现的参数选项
-XX:LargePageSizeInBytes=128m 内存页的大小, 不可设置过大, 会影响Perm的大小。
-XX:+UseFastAccessorMethods 原始类型的快速优化
-XX:+Disable‘’ExplicitGC 关闭System.gc()
JVM调优
JVM内存调优
导致Full GC一般由于以下几种情况:
旧生代空间不足
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象
新生代设置过小
一是新生代GC次数非常频繁,增大系统消耗;二是导致大对象直接进入旧生代,占据了旧生代剩余空间,诱发Full GC
2). 新生代设置过大
,.
一是新生代设置过大会导致旧生代过小(堆总量一定),从而诱发Full GC;二是新生代GC耗时大幅度增加
3). Survivor设置过小
导致对象从eden直接到达旧生代
4). Survivor设置过大
导致eden过小,增加了GC频率
一般说来新生代占整个堆1/3比较合适
GC策略的设置方式
1). 吞吐量优先 可由-XX:GCTimeRatio=n来设置
2). 暂停时间优先 可由-XX:MaxGCPauseRatio=n来设置
JVM内存管理:
JVM的常见的垃圾收集器:
G1收集器的阶段分以下几个步骤:
1、初始标记(它标记了从GC Root开始直接可达的对象)
2、并发标记(从GC Roots开始对堆中对象进行可达性分析,找出存活对象)
3、最终标记(标记那些在并发标记阶段发生变化的对象,将被回收)
4、筛选回收(首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)
GC调优:
基本的调优思路可以总结为:
1.理解应用需求和问题,确定调优目标。评估用户可接受的响应时间和业务量,将目标简化为,希望 GC 暂停尽量控制在 200ms 以内,并且保证一定标准的吞吐量。
2.掌握 JVM 和 GC 的状态,定位具体的问题,确定真的有 GC 调优的必要。比如,通过 jstat 等工具查看 GC 等相关状态,可以开启 GC 日志,或者是利用操作系统提供的诊断工具等
3.选择的 GC 类型是否符合我们的应用特征,如果是,具体问题表现在哪里,是 Minor GC 过长
4.通过分析确定具体调整的参数或者软硬件配置。
5.验证是否达到调优目标,如果达到目标,即可以考虑结束调优;否则,重复完成分析、调整、验证这个过程。
* GC日志分析
- 调优命令
- 调优工具
调优命令
Sun JDK监控和故障处理命令有jps jstat jmap jhat jstack jinfo
- jps,JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。
- jstat,JVM statistics Monitoring是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
- jmap,JVM Memory Map命令用于生成heap dump文件
- jhat,JVM Heap Analysis Tool命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看
- jstack,用于生成java虚拟机当前时刻的线程快照。
- jinfo,JVM Configuration info 这个命令作用是实时查看和调整虚拟机运行参数。
调优工具
常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool)、GChisto。
- jconsole,Java Monitoring and Management Console是从java5开始,在JDK中自带的java监控和管理控制台,用于对JVM中内存,线程和类等的监控
GC触发的条件有两种
(1)程序调用System.gc时可以触发;(2)系统自身来决定GC触发的时机。
Minor GC ,Full GC 触发条件
java内存模型
Java内存模型定义了多线程之间共享变量的可见性以及如何在需要的时候对共享变量进行同步。JMM 内部的实现通常是依赖于所谓的内存屏障,通过禁止某些重排序的方式,提供内存可见性保证,也就是实现了各种 happen-before 规则。
与JVM 内存模型不同。
java垃圾回收机制
一.如何确定某个对象是“垃圾”?
1)引用计数法。(python)
2) 在Java中采取了 可达性分析法
通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
二.典型的垃圾收集算法
(标记-清除)算法 (复制)算法 (标记-整理)算法 (分代收集)算法
三.典型的垃圾收集器
1.Serial:最古老的垃圾收集器,“Serial”体现在其收集工作是单线程的, 在进行垃圾收集过程中,会进入臭名昭著的“Stop-The-World”状态,一直是 Client 模式下 JVM 的默认选项。复制算法(-XX:+UseSerialGC)
Serial Old:老年代,采用了标记 – 整理(Mark-Compact)算法
2.ParNew:新生代 GC 实现,是 Serial GC 的多线程版本,最常见的应用场景是配合老年代的 CMS GC 工作(-XX:+UseParNewGC)
3.Parallel Scavenge: 新生代的多线程收集器(并行收集器) 其采用的是Copying算法,是 server 模式 JVM 的默认 GC 选择(-XX:+UseParallelGC)
4.Parallel Old:并行运行;作用于老年代;标记-整理算法;吞吐量优先;适用于后台运算而不需要太多交互的场景。
5.CMS:基于标记 – 清除(Mark-Sweep)算法,设计目标是尽量减少停顿时间,采用的标记 – 清除算法,存在着内存碎片化问题,所以难以避免在长时间运行等情况下发生 full GC(-XX:+UseConcMarkSweepGC),在 JDK 9 中被标记为废弃(deprecated)
6.G1(重点讲,引用上面的G1):兼顾吞吐量和停顿时间的 GC 实现,是 Oracle JDK 9 以后的默认 GC 选项。G1 可以直观的设定停顿时间的目标。
G1 同样存在着年代的概念,但是与我前面介绍的内存结构很不一样,其内部是类似棋盘状的一个个 region 组成。

region 的大小是一致的,数值是在 1M 到 32M 字节之间的一个 2 的幂值数,JVM 会尽量划分 2048 个左右、同等大小的 region。
当然这个数字既可以手动调整,G1 也会根据堆大小自动进行调整。在 G1 实现中,年代是个逻辑概念,具体体现在,一部分 region 是作为 Eden,一部分作为 Survivor,除了意料之中的 Old region,G1 会将超过 region 50% 大小的对象(在应用中,通常是 byte 或 char 数组)归类为 Humongous 对象,并放置在相应的 region 中。逻辑上,Humongous region 算是老年代的一部分,
缺点:region 大小和大对象很难保证一致,这会导致空间的浪费。
从 GC 算法的角度,G1 选择的是复合算法,可以简化理解为:
在新生代,G1 采用的仍然是并行的复制算法,所以同样会发生 Stop-The-World 的暂停。
在老年代,大部分情况下都是并发标记,而整理(Compact)则是和新生代 GC 时捎带进行,并且不是整体性的整理,而是增量进行的。
jvm怎样判断一个对象是否可回收,怎样的对象才能作为GC root
OOM说一下?怎么排查?哪些会导致OOM? OOM出现在什么时候
什么是Full GC?GC? major GC? stop the world
JVM中类加载机制,类加载过程,什么是双亲委派模型? 类加载器有哪些
一般来说,我们把 Java 的类加载过程分为三个主要步骤:加载、链接、初始化,具体行为在Java 虚拟机规范里有非常详细的定义。
首先是加载阶段(Loading),它是 Java 将字节码数据从不同的数据源读取到 JVM 中,并映射为 JVM 认可的数据结构(Class 对象),这里的数据源可能是各种各样的形态,如 jar 文件、class 文件,甚至是网络数据源等;如果输入数据不是 ClassFile 的结构,则会抛出 ClassFormatError。
验证(Verification),这是虚拟机安全的重要保障,JVM 需要核验字节信息是符合 Java 虚拟机规范的,否则就被认为是 VerifyError,这样就防止了恶意信息或者不合规的信息危害 JVM 的运行,验证阶段有可能触发更多 class 的加载。
准备(Preparation),创建类或接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显式初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行更进一步的 JVM 指令。
解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。在Java 虚拟机规范中,详细介绍了类、接口、方法和字段等各个方面的解析。
如何判断是否有内存泄露?
Java 中都有哪些引用类型?
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/172714.html原文链接:https://javaforall.net
