p7付费课程笔记3:JVM 启动参数

文章详细介绍了JVM的启动参数,包括标准参数、非标准参数和非稳定参数,以及它们在内存分配、垃圾回收和系统属性设置中的作用。重点讨论了堆内存的-Xms和-Xmx等参数,以及GC相关参数如-XX:+UseG1GC。还提到了JavaAgent的概念,用于无侵入式增强应用功能。文章强调了正确配置JVM参数以避免内存溢出和性能问题的重要性。
摘要由CSDN通过智能技术生成

目录

jvm启动参数

参数分类

系统属性

功能解析

运行模式

jvm有两种运行模式

堆内存

设置堆内存

GC相关

GC 日志相关的参数

分析诊断

指定垃圾收集器相关参数

JavaAgent

什么是Java agent

常见问题

视频


前言

这堂课程不用过多的记忆,自身有印象即可。当然一些常用的最好还是了解一些比较好。

jvm启动参数

JVM(Java虚拟机)的启动参数是在启动JVM时可以设置的一些命令行参数。这些参数用于指定JVM的运行环境、内存分配、垃圾回收器以及其他选项。以下是一些常见的JVM启动参数:

  1. -Xms:设置JVM的初始堆大小。

  2. -Xmx:设置JVM的最大堆大小。

  3. -Xss:设置每个线程的栈大小。

  4. -XX:MaxMetaspaceSize:设置元空间(在JDK8之后替代了永久代)的最大大小。

  5. -XX:PermSize:设置永久代的初始大小。

  6. -XX:MaxPermSize:设置永久代的最大大小(在JDK8之前使用)。

  7. -XX:NewSize:设置新生代的初始大小。

  8. -XX:MaxNewSize:设置新生代的最大大小。

  9. -XX:SurvivorRatio:设置Eden区和Survivor区的比例。

  10. -XX:+UseParallelGC:使用并行垃圾回收器。

  11. -XX:+UseConcMarkSweepGC:使用并发标记清除垃圾回收器。

  12. -verbose:gc:打印GC日志信息。

  13. -Dproperty=value:设置系统属性。

这些启动参数可以通过在命令行中使用"java"命令时添加参数来设置。例如:"java -Xms256m -Xmx512m -jar myapp.jar"将设置JVM的初始堆大小为256MB,最大堆大小为512MB,并运行名为"myapp.jar"的Java应用程序。

idea使用

参数分类

1. 以 - 开头为标准参数,所有的 JVM 都要实现这些参数,并且向后兼容,如 -server。 2. -D 设置系统属性,如 -Dfile.encoding=UTF-8。 3. 以 -X 开头为非标准参数,基本都是传给 JVM 的,默认 JVM 实现这些参数的功能,但是并不保证所有 JVM 实现都满足,且不保证向后兼容。 可以使用 java -X 命令来查看当前 JVM 支持的非标准参数,如 -Xmx8g。 4. 以 –XX:开头为非稳定参数, 专门用于控制 JVM 的行为,跟具体的 JVM 实现有关,随时可能会在下个版本取消。 -XX:±Flags 形式, ± 是对布尔值进行开关,如 -XX:+UseG1GC。 -XX:key=value 形式, 指定某个选项的值,如 -XX:MaxPermSize=256m。

JVM启动参数使用中常见的错误:

java.lang.OutOfMemoryError相信很多开发人员都用到过,这个主要就是JVM参数没有配好引起的,但是这种错误又分两种:java.lang.OutOfMemoryError:Javaheapspace和java.lang.

OutOfMemoryError:PermGenspace,其中前者是有关堆内存的内存溢出,可以同过配置-Xms和-Xmx参数来设置,而后者是有关永久域的内存溢出,可以通过配置-XX:MaxPermSize来设置。

系统属性

其他语言不清楚,但是作为java中,无论你去哪个公司,只要是使用新的电脑。工作第一个本职工作一般都是配置系统环境变量。比如我们的jdk等,服务器部署也是一样的。

这里我们可以使用System.getProperty("")方法来进行配置,现在很少了。了解即可。

java -D 配置系统属性 使用案例 其实,在不知不觉中我们已经在使用-D的参数项,比如用下面参数来配置文件编码: -Dfile.encoding=UTF-8

再比如,用以下参数来配置dubbo的选项: java -Ddubbo.reference.com.foo.BarService.check=false java -Ddubbo.reference.check=false java -Ddubbo.consumer.check=false java -Ddubbo.registry.check=false

功能解析

-D=value 官网解释:

Set a system property value. If value is a string that contains spaces, you must enclose the string in double quotes: 在虚拟机的系统属性中设置属性名/值对,运行在此虚拟机上的应用程序可用: System.getProperty("属性名")

得到value的值。 如果value中有空格,则需要用双引号将该值括起来,如:-Dname=”kazaf f”。 该参数通常用于设置系统级全局变量值,如配置文件路径,保证该属性在程序中任何地方都可访问。 注意事项 (1)需要设置的是JVM参数而不是program参数; (2)使用此参数的参数优先级最高,会覆盖项目中配置的此项;

运行模式

jvm有两种运行模式

Client:

JDK1.7 之前在 32 位的 x86 机器上的默认值是 -client 选项。设置 jvm 使用 client 模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或者PC应用开发和调试。

Server:

设置 jvm 使 server 模式,特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境。在具有 64 位能力的 jdk 环境下将默认启用该模式,而忽略 -client 参数。

JVM的两种运行模式Server与Client。两种模式的区别在于,Client模式启动速度较快,Server模式启动较慢;但是启动进入稳定期长期运行之后Server模式的程序运行速度比Client要快很多。这是因为Server模式启动的JVM采用的是重量级的虚拟机,对程序采用了更多的优化;而Client模式启动的JVM采用的是轻量级的虚拟机。所以Server启动慢,但稳定后速度比Client远远要快。

-Xint:

在解释模式(interpreted mode)下,-Xint 标记会强制 JVM 解释执行所有的字节码,这当然会降低运行速度,通常低 10 倍或更多。

-Xcomp:

-Xcomp 参数与 -Xint 正好相反,JVM 在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。

-Xmixed:

-Xmixed 是混合模式,将解释模式和变异模式进行混合使用,有 JVM 自己决定,这是 JVM 的默认模式,也是推荐模式。 我们使用java -version 可以看到 mixed mode 等信息。

堆内存

JVM 总内存=堆+栈+非堆+堆外内存

设置堆内存

JVM 的内存设置是最重要的参数设置,也是 GC 分析和调优的重点。JVM 总内存=堆+栈+非堆+堆外内存。

-Xmx:

指定最大堆内存。 如 -Xmx4g. 这只是限制了 Heap 部分的最大值为 4g。这个内存不包括栈内存,也不包括堆外使用的内存。

-Xms:

指定堆内存空间的初始大小。 如 -Xms4g。 而且指定的内存大小,并不是操作系统实际分配的初始值,而是 GC 先规划好,用到才分配。 专用服务器上需要保持 -Xms和-Xmx一致,否则应用刚启动可能就有好几个 FullGC。当两者配置不一致时,堆内存扩容可能会导致性能抖动。

-Xmn:

等价于 -XX:NewSize,使用 G1 垃圾收集器 不应该 设置该选项,在其他的某些业务场景下可以设置。官方建议设置为 -Xmx 的 1/2 ~ 1/4。

-XX:MaxPermSize=size:

这是 JDK1.7 之前使用的。Java8 默认允许的 Meta 空间无限大,此参数无效。

-XX:MaxMetaspaceSize=size:

Java8 默认不限制 Meta 空间, 一般不允许设置该选项。

XX:MaxDirectMemorySize=size:

系统可以使用的最大堆外内存,这个参数跟-Dsun.nio.MaxDirectMemorySize效果相同。

-Xss:

设置每个线程栈的字节数。 例如 -Xss1m 指定线程栈为 1MB,与-XX:ThreadStackSize=1m等价

注意:

堆外内存:也就是说不在堆上的内存,我们可以通过jconsole,jvisualvm 等工具查看。对于IBM JVM和Hotspot,都可以通过-XX:MaxDirectMemorySize来设置nio直接缓冲区的最大值。默认是64M。超过这个时,会按照32M自动增大。

系统有大量的地方使用堆外内存,远比我们常说的 xmx 和 xms 包括的范围要广。所以我们需要在设置内存的时候留有余地,一般来说配置系统或容器里可用内存的 60-80% 最好。

GC相关

​-XX:+UseG1GC: 使用 G1 垃圾回收器

-XX:+UseConcMarkSweepGC: 使用 CMS 垃圾回收器

-XX: +UseSerialGC: 使用串行垃圾回收器

-XX: +UseParallelGC: 使用并行垃圾回收器

/ Java 11+

XX: +UnlockExperimentalVMOptions -XX:+UseZGO/ Java 12+

-XX: +UnlockExperimentalVMOptions -XX:+UseShenandoahGO

GC 日志相关的参数

在生产环境或性能压测环境里,我们用来分析和判断问题的重要数据来源之一就是 GC 日志,JVM 启动参数为我们提供了一些用于控制 GC 日志输出的选项。

-verbose:gc :

和其他 GC 参数组合使用, 在 GC 日志中输出详细的GC信息。 包括每次 GC 前后各个内存池的大小,堆内存的大小,提升到老年代的大小,以及消耗的时间。此参数支持在运行过程中动态开关。比如使用 jcmd, jinfo, 以及使用 JMX 技术的其他客户端。

-XX:+PrintGCDetails 和 -XX:+PrintGCTimeStamps:

打印 GC 细节与发生时间。

-Xloggc:file:

与-verbose:gc功能类似,只是将每次 GC 事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。若与 verbose:gc 命令同时出现在命令行中,则以 -Xloggc 为准。

分析诊断

指定垃圾收集器相关参数

垃圾回收器是 JVM 性能分析和调优的核心内容之一,也是近几个 JDK 版本大力发展和改进的地方。通过不同的 GC 算法和参数组合,配合其他调优手段,我们可以把系统精确校验到性能最佳状态。

以下参数指定具体的垃圾收集器。

-XX:+UseG1GC:使用 G1 垃圾回收器

-XX:+UseConcMarkSweepGC:使用 CMS 垃圾回收器

-XX:+UseSerialGC:使用串行垃圾回收器

-XX:+UseParallelGC:使用并行垃圾回收器

JavaAgent

Agent 是 JVM 中的一项黑科技,可以通过无侵入方式来做很多事情,比如注入AOP 代码,执行统计等等,权限非常大。这里简单介绍一下配置选项,详细功能需要专门来讲。

设置 agent 的语法如下:

-agentlib:libname[=options] 启用 native 方式的 agent,参考 LD_LIBRARY_PATH 路径

-age-ntpath:pathname[=options] 启用 native 方式的 agent。

-javaagent:jarpath[=options] 启用外部的 agent 库,比如 pinpoint.jar 等等

-Xnoagent 则是禁用所有 agent

以下示例开启 CPU 使用时间抽样分析:

JAVA _OPTS="-agentlib:hprof=cpu=samples,file=cpu.samples.log"

什么是Java agent

Java agent 是从 JDK1.5开始引入的技术,支持将 jar 依附在 JVM 进程中运行。

Java agent 分为静态加载和动态加载两种agent加载的方式,如下图:

参考文档:https://blog.csdn.net/BASK2311/article/details/127491913

常见问题

1.既然jvm有的非标准参数是无法支持的,那么我们想使用的参数如何查询是否有效支持?

答案就是:java -x

2.以前工作时也碰到过课程视频中所说的,就是我们一个服务命名没有什么用户量,但是总是不断的oom。我们查看GC日志后没有明显的问题,这时候我就就需要看下启动参数了。

我们-xmx配置的最大内存数值一定不要超过本机服务器的80%,而xms也和xmx相同。

否则就没法给一些非堆内存和其他程序留出空间了。一般情况下直接配置60-80%即可,现在服务器一般都是1G起步。

3.Java中各大版本的默认垃圾回收器是什么?java8呢?这个我们会在后面的GC算法中讲到,又兴趣的可以自己先看看,到时候可以一起讨论。

4.为什么服务器上需要保持 -Xms和-Xmx一致

在Java虚拟机(JVM)中,-Xms参数用来设置堆内存的初始(或最小)大小,而-Xmx参数用来设置堆内存的最大大小。在服务器上保持-Xms-Xmx设置一致有几个优点:

  1. **防止动态扩展:**当-Xms-Xmx一致时,JVM在启动时就会预留全部的内存空间作为堆内存,并且在整个运行过程中堆的大小不会改变。这避免了运行时堆内存增长,减少了因动态扩展堆内存而造成的性能开销。

  2. **避免内存碎片:**动态调整堆内存可能导致更多的内存碎片产生。如果初始堆大小设置得过小,随着应用程序的运行,JVM可能需要不断地调整堆大小以满足内存需求,这种调整有时会导致额外的垃圾收集(GC)负载和内存碎片,影响性能。

  3. **预防应用抖动:**如果堆内存不断地进行扩容和收缩,可能会造成应用性能的抖动。一开始,应用在较小的堆内存中运行并开始请求更多的内存,JVM响应这些请求可能会引起停顿,影响应用的响应时间。固定堆大小可以保持性能的稳定性。

  4. **预留资源:**将-Xms-Xmx设置为一致,相当于是向JVM声明,服务器上有这么多内存是可以被应用充分利用的。通过这种方式,你可以确保操作系统不会因为JVM突然请求更多内存而承受额外的负载,这对于资源紧张的环境尤其重要。

  5. **简化垃圾收集行为:**JVM的垃圾收集器会根据堆内存的使用情况来调整其垃圾收集策略。当堆内存大小固定时,垃圾收集器可以更容易地管理这些内存,因为它知道内存不会动态变化,从而可能提高垃圾收集性能。

然而,并不是所有情况下都应当将-Xms-Xmx设置为同样的值。若你的应用内存使用量波动较大,或者你完全确信不会存在内存不足的问题,那么允许JVM在更小的初始堆内存上进行启动,以节约资源也是有意义的。

不同的应用程序和不同的运行环境需要不同的配置。对于一些长期运行和内存使用量稳定的服务器应用,保持-Xms-Xmx一致是一个常见的最佳实践,它有助于减少内存管理的复杂性并提高性能。但最重要的是根据实际情况和需求来合理配置这些参数。

视频

链接:https://www.aliyundrive.com/s/bfS1cHS9z8z

今天就到这里吧,感觉有用的小伙伴可以点个赞,你的支持就是我更新的最大动力!

  • 52
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你可以叫我老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值