1. 首页

JVM 参数调优(qbit)

前言

  • JVM 的参数有好几百个,听着有点吓人,好在最常用的参数只有两个,其他绝大多数参数都无需调整。可以参考廖雪峰的文章: JVM调优的正确姿势

-Xms8g -Xmx8g

Client/Server

  • JVM 有两种运行模式 Server 与 Client。
  • Client 模式启动速度较快,Server 模式启动较慢。
  • 启动进入稳定期长期运行之后 Server 模式的程序运行速度比 Client 要快很多。
  • 查看当前虚拟机处于哪种模式

λ java -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
  • 64 位 JDK 无法切换到 Clinet 模式

打印 JVM 参数

  • 打印 JVM 参数初始值

λ java -XX:+PrintFlagsInitial
  • 打印 JVM 参数最终值

λ java -XX:+PrintFlagsFinal 2> nul
  • 打印被修改过的 JVM 参数

# 输出经由人工换行 λ java -XX:+PrintCommandLineFlags 2> nul -XX:InitialHeapSize=266579392 -XX:MaxHeapSize=4265270272 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
  • 在 java 代码里面打印

import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; private void printJvm() { MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean(); System.out.println("堆内存信息: " + memorymbean.getHeapMemoryUsage()); System.out.println("方法区内存信息: " + memorymbean.getNonHeapMemoryUsage()); List<String> inputArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); System.out.println("\n####################运行时设置的JVM参数####################"); System.out.println(inputArgs); System.out.println("\n####################运行时内存情况#######################"); long totle = Runtime.getRuntime().totalMemory(); System.out.println("总的内存量 [" + totle + "]"); long free = Runtime.getRuntime().freeMemory(); System.out.println("空闲的内存量 [" + free + "]"); long max = Runtime.getRuntime().maxMemory(); System.out.println("最大的内存量 [" + max + "]"); }

jvm 内存模型

  • 图片来源于网络

image.png

常用参数


-Xms: 初始堆大小 -Xmx: 最大堆大小 -XX:NewSize: 年轻代初始化内存的大小(注意:该值需要小于-Xms的值) -XX:MaxnewSize: 年轻代可被分配的内存的最大上限(注意:该值需要小于-Xmx的值) 从 JKD1.4 开始,MaxnewSize 是通过 NewRatio 计算出来的 -Xmn: 对-XX:newSize、-XX:MaxnewSize两个参数同时进行配置(JDK1.4之后才有该参数) 官方推荐为对大小的 3/8,即 1/4 到 1/3 之间 -XX:NewRatio: 设置老年代和年轻代的比值 若 -Xmn 已指定,则 OldSize = HeapSize - NewSize,无需再按比例计算。 例如 NewRatio 为 3,表示 老年代/年轻代 = 3,年轻代占整个堆内存大小的 1/4
  • 对于年轻代的堆内存大小,默认情况下是通过 NewRatio(2) 计算出来的,即占用 1/3;在配置 Xmn 后,会覆盖默认的通过 NewRatio 计算出来的年轻代堆大小值

# 摘录的部分的输出行 # MaxHeapSize/MaxNewSize = 4265607168/1421869056 = 3 λ java -XX:+PrintFlagsFinal uintx NewRatio = 2 {product} uintx MaxNewSize := 1421869056 {product} uintx MaxHeapSize := 4265607168 {product}
  • 一般 -Xms、-Xmx 两个参数会配置相同的值(优点:能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源)。

CompressedOops

压缩普通对象指针

compressed ordinary object pointers,压缩普通对象指针


(0, 2GB] Compressed Oops mode: 32-bit [2GB, 26GB] Compressed Oops mode: Zero based,26G不是确切值,视系统而定 (26GB, 32GB) Compressed Oops mode: Non-zero disjoint base,32G不是确切值,视系统而定 [32GB, ) CompressedOops 失效,32G不是确切值,视系统而定

CompressedOops

检查 CompressedOops 阈值

  • 下面测试的粒度为 GB,也可以到 MB
  • 以下命令适用于 JDK7/JDK8

# 测试环境 Windows 10 JDK7

# CompressedOops 阈值 # 32 G,false 表示超过了阈值 > java -Xmx32g -XX:+PrintFlagsFinal 2> nul | findstr UseCompressedOops bool UseCompressedOops = false {lp64_product} # 31G,true 表示在阈值之内 > java -Xmx31g -XX:+PrintFlagsFinal 2> nul | findstr UseCompressedOops bool UseCompressedOops := true {lp64_product}

# zero based Compressed Oops 阈值 # 32G,未启用压缩 > java -server -Xms32G -Xmx32G -XX:+UseConcMarkSweepGC -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode) # zero based Compressed Oops 阈值 # 30G,Non-zero > java -server -Xms30G -Xmx30G -XX:+UseConcMarkSweepGC -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version Protected page at the reserved heap base: 0x000000007fff0000 / 65536 bytes heap address: 0x0000000080000000, size: 30802 MB, Compressed Oops with base: 0x000000007ffff000 java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode) # 30G,Zero based > java -server -Xms29G -Xmx29G -XX:+UseConcMarkSweepGC -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version heap address: 0x00000000bae00000, size: 29778 MB, zero based Compressed Oops java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

测试案例


这个案例中,分配 32g 比 31g 能创建的对象少了 50% 587889429/385481085 ≈ 1.525

35GB小于32GB


这个案例中,48g 才基本达到 31g 的效果

48GB=31GB

本文出自 qbit snap

作者:qbit
链接:https://segmentfault.com/a/1190000022603726

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:JVM 参数调优(qbit)

链接:https://www.javascriptc.com/4029.html

« 基于 Flutter+Dart 聊天实例 | Flutter 仿微信界面聊天室
IDC:2019 下半年中国整体云专业服务市场达 68.8 亿元»
Flutter 中文教程资源

相关推荐

QR code