Administrator
Administrator
发布于 2026-09-05 / 1 阅读
0
0

从阿里云2h2g迁移到Azure 2h1g小鸡

从阿里云2h2g迁移到Azure 2h1g小鸡

QA:Halo博客迁移的 JVM 参数调优理解


Q:为什么容器里 JVM 自动用了 SerialGC,我没配这个参数啊?

A: JVM 的 ergonomic 机制会根据机器配置自动选择垃圾收集器。当容器内存 < 1792MB 或核心数不足时,JVM 判定为非"Server-class",自动降级为 SerialGC。这是 JVM 的默认行为。在我的2h1g小鸡🐣上就是了,

# 调优前先看 JVM 自动选择了什么GC
java -XX:+PrintFlagsFinal -version | grep Use.*GC

# 输出
bool UseG1GC           = false  {product}           # 没选
bool UseSerialGC       = true   {ergonomic}         # ✅ 自动选的
bool UseZGC            = false  {product}           # 没选

结果就是自动选了SerialGC,单核单线程

小Q:为什么自动选了 SerialGC?

JVM 的 Ergonomics 规则:

if (CPU核数 ≥ 2 且 内存 ≥ 1792MB):
→ Server-class → 默认 G1GC
else:
→ 非 Server-class → 强制 SerialGC


Q:{ergonomic} 这个标记是什么意思?

A: 表示该参数由 JVM 自动推导 设置,非用户显式配置。常见于 -XX:+PrintFlagsFinal 的输出中,用来区分"人配的"还是"机器自己选的"。


Q:我想确认 JVM 实际生效的参数,用什么命令?JVM是依据什么环境判断的?

A:

java -XX:+PrintFlagsFinal -version | grep GC

或查看具体某参数:

java -XX:+PrintFlagsFinal -version | grep UseSerialGC

每次执行命令都是基于运行哪个终端的机器环境来的,docker的话就是分配给docker的cpu/memery。如:

物理机: 64核 256GB

(分给你的云服务器)容器 limit: 2核 891MB ← JVM 只看这个

JVM 判定: "小破机器,不配用 G1" → 自动选 SerialGC


最终本次迁移服务器本网站采用配置:

environment:
  - JVM_OPTS=-Xmx256m -Xms256m -Xss512k -XX:MaxMetaspaceSize=192m
             -XX:MaxDirectMemorySize=96m -XX:ReservedCodeCacheSize=64m
             -XX:+UseSerialGC -XX:TieredStopAtLevel=1
mem_limit: 640m

PostgreSQL 顺手调小了
发现 Halo 的连接池配置得很大,PostgreSQL 有一堆 idle(空闲)连接。这个小数据库根本用不上这么豪华的配置。

修改:

command: [postgres, -c, shared_buffers=32MB, -c, max_connections=30, -c, effective_cache_size=128MB]
shared_buffers:从默认 128MB → 降到 32MB

max_connections:从默认 100 → 降到 30

效果:PostgreSQL 内存占用从 57 MB 降到 55 MB(变化不大,但配置更合理了)。

总结:

  • 本次迁移部署Halo博客调优jvm真有用的部分就是把编译器从默认4层的C2调为C1快速编译,并且因为内存过小选择单线程Sercial GC回收,还将xmxxms堆内存限制大小和一些其他边角的jvm类内存限制,直接内存、元空间、代码缓存、单线程大小啥的。小并发用不上C2为了上万并发优化的编译器和G1这个6G左右的大堆GC。

评论