netty 按需声明,并记录 jar 运行期的低内存调优

netty-all 是聚合 pom,会拖进 5 个平台的 native-quic、各架构的 epoll/kqueue/
io_uring 传输以及 htt3/mqtt/redis 等一堆用不到的 codec。主站实际只用
Bootstrap/NioEventLoopGroup/NioSocketChannel/ByteBuf/ByteToMessageCodec/
LengthFieldBasedFrameDecoder/LoggingHandler/Promise,因此收敛为
transport + codec-base + handler(含 buffer/common/resolver 传递依赖)。

效果:jar 68.1MB -> 52.2MB,netty 模块 50 -> 7,进程 RSS 291MB -> 约 227MB。
433 个测试全绿。hutool 未动。

同时把 jar 运行期的 systemd JVM 参数与前后实测数据记入
docs/MEMORY_TUNING_2026-09-21.md,避免这些只存在于服务器 drop-in 的参数
在下次重新部署时丢失。
This commit is contained in:
root
2026-09-21 17:27:17 +08:00
parent 5f1066cdab
commit e03a2e007b
2 changed files with 100 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
# 2026-09-21 低内存调优记录(jar 运行期)
编译机未上线期间,两个后端都以 jar 方式运行。本机为 2 核 / 2.9G,活跃堆很小但 RSS 偏高,
做了一轮只改 JVM 参数与依赖声明的低内存调优。全程未改业务代码。
## 实测前后对照
| 服务 | 项目 | 调优前 | 调优后 |
| --- | --- | --- | --- |
| 主站 lionwebsite | RSS | 291 MB | 约 227 MB |
| 主站 lionwebsite | jar 体积 | 68.1 MB | 52.2 MB |
| 主站 lionwebsite | netty 模块 | 50 个 | 7 个 |
| 主站 lionwebsite | 线程数 | 40 | 37 |
| 存储节点 storageNode | RSS | 171 MB | 约 155-162 MB |
| 存储节点 storageNode | netty 模块 | 35 个 | 5 个 |
| 存储节点 storageNode | 线程数 | 24 | 20-22 |
调优前后堆使用都在 40-52 MB 量级,RSS 的主要成分是元空间、代码缓存与各类映射,
因此收益主要来自收敛预留和减少类加载面,而不是堆。
## 一、JVM 参数(systemd drop-in,不在版本控制内)
主站 `/etc/systemd/system/lionwebsite.service.d/jar-run.conf`:
/usr/local/jdk-25/bin/java -Xmx256m -Xss512k -XX:MaxMetaspaceSize=160m \
-XX:+UseSerialGC -XX:+UseCompactObjectHeaders \
-XX:ReservedCodeCacheSize=96m -XX:+ExitOnOutOfMemoryError \
-jar /home/lionwebsite/lionwebsite.jar
存储节点 `/etc/systemd/system/storageNode.service.d/jar-run.conf`:
/usr/local/jdk-25/bin/java -Xmx192m -Xss512k -XX:MaxMetaspaceSize=96m \
-XX:+UseSerialGC -XX:+UseCompactObjectHeaders \
-XX:ReservedCodeCacheSize=96m -XX:+ExitOnOutOfMemoryError \
-cp /root/gallery/storageNode/storageNode-jar.jar:/root/gallery/storageNode/lib/* lion.Main
取值依据:
- `UseSerialGC`:小堆、低吞吐场景,省掉 G1 的分区元数据与并发标记线程。存储节点原本就是默认 SerialGC,主站原本是默认 G1,本次对齐。
- `UseCompactObjectHeaders`:对象头 12 到 8 字节,堆内以 String 与 map 节点为主时收益直接。
- `ReservedCodeCacheSize=96m`:原先 240m 预留,实测主站只用约 14 MB、节点约 6 MB。
- `-Xmx` 收敛:主站由 384m 到 256m,节点由 256m 到 192m,相对活跃堆仍留 4-6 倍余量。
回滚:恢复同目录 `jar-run.conf.bak.20260921T090605Z`(主站)或
`jar-run.conf.bak.20260921T090746Z`(节点)后 `daemon-reload` 加 `restart`。
## 二、依赖精简(已入库)
`netty-all` 是聚合 pom,会拖进全部模块。两个后端只用到 NIO 传输与基础编解码,
因此改为按需声明:
- 主站(netty 4.2.17):`netty-transport` 加 `netty-codec-base` 加 `netty-handler`。
`handler` 用于 `RemoteService` 的 `LoggingHandler` 协议调试日志。
- 存储节点(netty 4.1.138):`netty-transport` 加 `netty-codec`。
节点侧未使用 `handler` 模块的类,故不声明。4.1 无独立 `codec-base`,编解码基类在 `netty-codec`。
剔除的内容包括 5 个平台的 native-quic、aarch64 与 riscv64 与 osx 的 epoll 与 kqueue 与 io_uring 传输、
以及 codec-http3 与 mqtt 与 redis 与 smtp 与 stomp 与 xml 与 protobuf 等。
`hutool-all` 未调整。
## 三、已评估但未采用:AOT 缓存
JDK 25 的 `-XX:AOTCache` 可免原生编译生成类缓存。实测交替 A/B 各两轮:
| | 启动耗时 | RSS |
| --- | --- | --- |
| 无 AOT | 6.37s / 6.74s | 220.9 MB / 223.1 MB |
| 带 AOT | 6.27s / 6.36s | 221.4 MB / 222.7 MB |
启动约快 0.2s(噪声量级),RSS 与元空间均无改善,代价是 80 MB 缓存文件且每次发版需重训。
按降低内存的目标不值得,故未在生产启用。
## 四、遗留与后续
- 原生编译机恢复后应重新评估原生镜像:内存会显著低于 jar,届时上述 JVM 参数失去意义。
- 存储节点目录内仍保留 `lib.bak.20260921T091617Z`(47 jar)与 `storageNode.jar.bak.*`,为本次回滚路径。
- 两个 `jar-run.conf` 的 JVM 参数只存在于服务器 drop-in,未纳入版本控制;重新部署时需按本文恢复。
+22 -1
View File
@@ -86,7 +86,28 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<!--
只保留实际用到的模块。原先的 netty-all 是聚合 pom,会拖进 50 个模块
(含 5 个平台的 native-quic、aarch64/riscv64/osx 的 epoll/kqueue/io_uring、
codec-http3/mqtt/redis/smtp/stomp/xml/protobuf 等),
而本项目只用 Bootstrap/NioEventLoopGroup/NioSocketChannel/ByteBuf/
ByteToMessageCodec/LengthFieldBasedFrameDecoder/LoggingHandler/Promise。
transport 提供 Bootstrap/EventLoop/Channel,codec-base 提供
ByteToMessageCodec 与 LengthFieldBasedFrameDecoder,handler 提供
LoggingHandler(RemoteService 的协议调试日志用)。
buffer/common/resolver 由它们传递引入。
-->
<artifactId>netty-transport</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-base</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</dependency>
<dependency>