Java 程序的性能優化是一個系統性的工程,涉及代碼層面、JVM 調優、架構設計、併發控制等多個維度。本文將從多個角度出發,介紹提升 Java 程序性能的有效策略和實戰技巧,幫助你打造高效、穩定、可擴展的 Java 應用。


一、代碼層面的優化

1. 避免不必要的對象創建

頻繁創建和銷燬對象會增加 GC 壓力,影響性能。應儘量複用對象,特別是在循環或高頻調用的方法中。

優化前:

for (int i = 0; i < 1000; i++) {
    String s = new String("hello");
}

優化後:

String s = "hello";
for (int i = 0; i < 1000; i++) {
    // 複用同一個字符串對象
}

2. 使用 StringBuilder 代替字符串拼接

在循環中進行字符串拼接時,使用 StringBuilder 可以顯著提高性能。

優化前:

String result = "";
for (int i = 0; i < 1000; i++) {
    result += "line " + i;
}

優化後:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("line ").append(i);
}
String result = sb.toString();

3. 避免使用 finalize() 方法

finalize() 方法由垃圾回收器調用,調用時機不確定,且影響 GC 效率。應改用 try-with-resources 或顯式清理機制。

4. 使用基本類型代替包裝類

在性能敏感的場景中,應優先使用 intdouble 等基本類型,避免使用 IntegerDouble 等包裝類,以減少內存佔用和自動拆裝箱開銷。


二、JVM 調優

1. 調整堆內存大小

通過 -Xms 和 -Xmx 設置 JVM 初始堆和最大堆內存,避免頻繁擴容。

java -Xms512m -Xmx1024m MyApp

2. 選擇合適的垃圾收集器

根據應用場景選擇 GC 策略:

  • 吞吐量優先:使用 -XX:+UseParallelGC
  • 低延遲優先:使用 -XX:+UseG1GC 或 -XX:+UseZGC
  • 小內存或嵌入式:使用 -XX:+UseSerialGC

示例:

java -XX:+UseG1GC -Xms2g -Xmx2g MyApp

3. 監控 GC 日誌

開啓 GC 日誌,分析垃圾回收行為,定位性能瓶頸。

java -Xlog:gc*:file=gc.log MyApp

4. 類加載與元空間優化

調整元空間大小,避免 OutOfMemoryError: Metaspace

-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m

三、併發編程優化

1. 合理使用線程池

避免頻繁創建線程,使用 ThreadPoolExecutor 或 Executors 工廠類管理線程資源。

ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> {
    // 任務邏輯
});

2. 使用併發集合

在多線程環境下,優先使用 ConcurrentHashMapCopyOnWriteArrayList 等併發集合,避免 synchronized 帶來的性能損失。

3. 減少鎖競爭

  • 縮小同步塊範圍
  • 使用 ReadWriteLock 替代 synchronized
  • 使用 java.util.concurrent.atomic 包下的原子類

四、I/O 與網絡優化

1. 使用 NIO 替代傳統 I/O

Java NIO(New I/O)採用非阻塞模式,支持多路複用,適合高併發場景。

Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

2. 使用緩衝流

文件讀寫時使用 BufferedInputStream 和 BufferedOutputStream 提高效率。

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"));

3. 使用 HTTP/2 或異步 HTTP 客户端

對於 HTTP 請求,可使用如 OkHttpApache HttpClient 等支持異步請求的客户端,提高吞吐量。


五、數據庫訪問優化

1. 使用連接池

使用 HikariCPDruid 等高性能數據庫連接池,減少連接建立和釋放的開銷。

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("user");
config.setPassword("password");
HikariDataSource ds = new HikariDataSource(config);

2. 批量操作

避免逐條插入數據,使用批量 SQL 提高效率。

PreparedStatement ps = conn.prepareStatement("INSERT INTO users VALUES (?, ?)");
for (User user : users) {
    ps.setString(1, user.getName());
    ps.setInt(2, user.getAge());
    ps.addBatch();
}
ps.executeBatch();

3. 合理使用索引

確保 SQL 查詢中的字段有合適的索引,避免全表掃描。


六、緩存策略

1. 本地緩存

使用 Caffeine 或 Guava Cache 實現本地緩存,減少重複計算或數據庫訪問。

Cache<String, String> cache = Caffeine.newBuilder()
    .maximumSize(1000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build();

2. 分佈式緩存

對於分佈式系統,可使用 RedisMemcached 等緩存中間件,提高系統整體性能。


七、架構設計優化

1. 微服務化

將單體應用拆分為多個微服務,降低耦合,提升擴展性和可維護性。

2. 異步化處理

使用消息隊列(如 KafkaRabbitMQ)實現異步處理,提高系統吞吐量。

3. CDN 與靜態資源分離

將靜態資源(圖片、JS、CSS)部署到 CDN,減輕服務器壓力,加快用户訪問速度。


八、性能監控與分析工具

1. JProfiler / VisualVM

監控 CPU、內存、線程狀態,定位性能瓶頸。

2. Arthas

阿里巴巴開源的 Java 診斷工具,支持在線排查問題。

3. Prometheus + Grafana

搭建性能監控平台,實時監控 JVM 指標與應用狀態。