How Upgrading to JDK 17 and ZGC Boosted Meituan’s Service Performance by 10%
This article explains the key new features of JDK 17, demonstrates how Meituan upgraded core services to JDK 17 with ZGC, and shares detailed performance, stability and cost‑reduction results, along with migration steps, compatibility fixes and practical JVM tuning advice.
1. JDK 17 Main Features
JDK 17 introduces language enhancements (var type inference, sealed classes, records, switch expressions, text blocks), new APIs (HttpClient, jpackage, ProcessHandle), and numerous performance and bug fixes that improve code conciseness, safety and efficiency.
1.1 Language Features
1.1.1 Local Variable Type Inference
String str = "Hello world"; // JDK8
var str = "Hello world"; // JDK171.1.2 Sealed Classes
public sealed class Shape permits Circle, Rectangle, Triangle { }
public final class Circle extends Shape { float radius; }
public non-sealed class Square extends Shape { double side; }
public sealed class Rectangle extends Shape permits FilledRectangle { double length, width; }1.1.3 Record Classes
Records provide immutable data carriers with automatically generated equals(), hashCode(), toString() and constructors.
record Rectangle(double length, double width) { }
public final class Rectangle { private final double length; private final double width; public Rectangle(double length, double width) { this.length = length; this.width = width; } /* equals, hashCode, toString */ }1.1.4 Switch Expression Optimization
// JDK8
switch (day) { case MONDAY: num = 6; break; /* ... */ }
// JDK17
int num = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; default -> throw new IllegalStateException("Invalid day: " + day); };1.1.5 Text Blocks
String sql = """
SELECT * FROM users WHERE name = 'Alice'
""";1.1.6 instanceof Pattern Matching
if (obj instanceof String str) { System.out.println(str.length()); }1.1.7 NullPointerException Improvements
// JDK8
user.getAddress().getCity().toLowerCase();
// JDK17 provides detailed cause in the exception message.1.1.8 Collections, Stream and Optional Enhancements
Immutable factories (List.of, Set.of, Map.of), new Stream methods (takeWhile, dropWhile, iterate, ofNullable) and Optional methods (ifPresentOrElse, or, stream) simplify code.
1.2 New APIs and Tools
1.2.1 HttpClient
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
HttpResponse<String> resp = client.send(request, HttpResponse.BodyHandlers.ofString());1.2.2 jpackage
Creates native installers (exe, dmg) that bundle the JDK, eliminating the need for a separate runtime.
1.2.3 Process API
ProcessBuilder pb = new ProcessBuilder("echo", "Hello World!");
Process p = pb.start();
System.out.println(p.info().commandLine().orElse("<na>"));1.2.4 AI SDK Minimum Version
Modern AI SDKs (e.g., Spring AI) require at least JDK 17.
2. JDK 17+ZGC in Security Domain
2.1 Meituan JDK Landscape
Production primarily runs Oracle JDK 8u201, OpenJDK 17 and OpenJDK 11.
2.2 ZGC Suitable Scenarios
Large‑scale servers (>100 nodes, >16 C/16 G, heap >16 G), high CPU utilization, and GC‑heavy flame‑graphs benefit from ZGC.
2.3 ZGC Effects
2.3.1 Performance Benchmarks
TP9999 latency reduced by 180‑380 ms (18‑74%).
TP999 latency reduced by 60‑125 ms (10‑63%).
TP99 latency reduced by 3‑20 ms (0‑25%).
2.3.2 Case 1 – Intelligent Decision System (JDK 11+CMS → JDK 17+ZGC)
CPU busy dropped from 47.86% to 41.49% and long‑tail latency stabilized over 15 days.
Service error count fell from ~6000 to 349.
2.3.3 Case 2 – Content Security Core Service (JDK 8+CMS → JDK 17+ZGC)
GC pause impact on requests dropped from 0.196% to negligible, and latency improvements matched theoretical expectations.
2.4 ZGC Implementation Overview
ZGC uses a largely concurrent mark‑copy algorithm with only three short STW phases (initial mark, final mark, initial relocation), achieving sub‑10 ms pauses regardless of heap size.
Single‑generation design (no Young GC).
Region‑based heap with flexible sizes.
Partial compaction and NUMA awareness.
Colored pointers store GC metadata, eliminating object‑header overhead.
Read barriers ensure safe concurrent marking and relocation.
3. JDK 17 Upgrade Practice
The migration consists of installation, compatibility resolution, and performance testing.
3.1 Installation & Compatibility
Typical errors stem from Java module encapsulation (e.g., InaccessibleObjectException). The fix is to add --add-opens JVM arguments for required packages.
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED …3.2 Performance Testing
Baseline: JDK 8+CMS. Metrics collected: peak/average CPU, TP9999, error count, GC time, heap/metaspace usage.
3.3 JVM Parameters
-Xmx12g -Xms12g -XX:+UseZGC -XX:ConcGCThreads=3 -XX:ParallelGCThreads=8 -XX:+HeapDumpOnOutOfMemoryError …4. Conclusion
ZGC delivers superior latency and reduces machine cost.
Spring AI SDKs require JDK 17, making the upgrade future‑proof.
Direct migration from JDK 8 to 17 may need extensive compatibility work; a staged upgrade via JDK 11 can ease transition.
AI assistants can help resolve migration issues quickly.
Meituan Technology Team
Over 10,000 engineers powering China’s leading lifestyle services e‑commerce platform. Supporting hundreds of millions of consumers, millions of merchants across 2,000+ industries. This is the public channel for the tech teams behind Meituan, Dianping, Meituan Waimai, Meituan Select, and related services.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
