Java

エンタープライズの標準、JVM上で動作

Javaとは

Javaは1995年にSun Microsystems(現Oracle)が開発したオブジェクト指向言語です。 「Write Once, Run Anywhere」を掲げ、JVM上でプラットフォームに依存せず動作します。 エンタープライズシステム、Android、ビッグデータ処理で広く使用されています。

Java実行アーキテクチャ

JVM(Java Virtual Machine)の構造
クラスローダー
.classファイル読み込み
実行エンジン
インタプリタ + JIT
メモリ管理
ヒープ + GC
ネイティブIF
JNI

メモリ領域

Heap

オブジェクト格納、GC対象

Stack

ローカル変数、メソッド呼び出し

Metaspace

クラスメタデータ(Java 8+)

JITコンパイラ

HotSpot JVMはC1(クライアント)とC2(サーバー)の2つのJITコンパイラを持ちます。 頻繁に実行されるコード(ホットスポット)を検出し、段階的に最適化します。

C1 コンパイラ

  • • 高速にコンパイル
  • • 軽量な最適化
  • • 起動時間重視

C2 コンパイラ

  • • 高度な最適化
  • • コンパイル時間は長い
  • • ピーク性能重視

Tiered Compilation(段階的コンパイル):最初はインタプリタ → C1で軽く最適化 → ホットなコードはC2で徹底最適化

ガベージコレクション(GC)

JVMは自動メモリ管理(GC)を提供。用途に応じて複数のGCアルゴリズムを選択可能。

G1 GC(デフォルト、Java 9+)

リージョンベース。停止時間目標を設定可能。汎用的。

-XX:+UseG1GC
ZGC(Java 15+)

超低レイテンシ(<10ms)。大容量ヒープ向け。

-XX:+UseZGC
Shenandoah

低レイテンシ。コンカレントコンパクション。

-XX:+UseShenandoahGC

主要なJVMオプション

1# メモリ設定
2java -Xms512m -Xmx2g -jar app.jar
3# -Xms: 初期ヒープサイズ
4# -Xmx: 最大ヒープサイズ
5
6# GC設定
7java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
8
9# GCログ出力(Java 9+)
10java -Xlog:gc*:file=gc.log:time,level,tags -jar app.jar
11
12# コンテナ対応(Java 10+はデフォルト有効)
13java -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -jar app.jar
14
15# JIT最適化ログ
16java -XX:+PrintCompilation -jar app.jar
17
18# ヒープダンプ(OOM時)
19java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof -jar app.jar

Spring Boot アーキテクチャ

Spring BootはJavaのデファクトスタンダードWebフレームワーク。 組み込みTomcat/Jettyを使い、JARファイル1つでアプリケーションをデプロイ可能。

クライアント
組み込みTomcat
DispatcherServlet
Controller
1// Spring Boot アプリケーション
2@SpringBootApplication
3public class Application {
4 public static void main(String[] args) {
5 SpringApplication.run(Application.class, args);
6 }
7}
8
9@RestController
10@RequestMapping("/api/users")
11public class UserController {
12
13 @Autowired
14 private UserService userService;
15
16 @GetMapping("/{id}")
17 public ResponseEntity<User> getUser(@PathVariable Long id) {
18 return userService.findById(id)
19 .map(ResponseEntity::ok)
20 .orElse(ResponseEntity.notFound().build());
21 }
22
23 @PostMapping
24 public ResponseEntity<User> createUser(@RequestBody @Valid UserDto dto) {
25 User user = userService.create(dto);
26 return ResponseEntity.status(HttpStatus.CREATED).body(user);
27 }
28}

SRE/インフラ観点

監視項目

  • ヒープ使用率: Xmxに対する使用量
  • GC頻度/停止時間: STW(Stop-The-World)時間
  • スレッド数: アクティブスレッド、デッドロック
  • クラスローディング: Metaspace使用量

コンテナ化の注意点

  • • Java 8u131以前はcgroup制限を認識しない
  • -XX:MaxRAMPercentageでコンテナメモリの割合を指定
  • • ヒープ外メモリ(Metaspace、スレッドスタック)も考慮

起動時間最適化

  • CDS(Class Data Sharing): クラスメタデータを共有
  • AppCDS: アプリケーションクラスも対象
  • GraalVM Native Image: AOTコンパイルで即座に起動

Docker構成例

1# マルチステージビルド
2FROM eclipse-temurin:21-jdk AS builder
3WORKDIR /app
4COPY . .
5RUN ./gradlew bootJar --no-daemon
6
7FROM eclipse-temurin:21-jre
8WORKDIR /app
9
10# セキュリティ: 非rootユーザー
11RUN addgroup --system app && adduser --system --ingroup app app
12USER app
13
14COPY --from=builder /app/build/libs/*.jar app.jar
15
16# JVM設定
17ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
18
19EXPOSE 8080
20ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
1# Kubernetes Deployment
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: java-app
6spec:
7 template:
8 spec:
9 containers:
10 - name: app
11 image: myapp:latest
12 resources:
13 requests:
14 memory: "512Mi"
15 cpu: "500m"
16 limits:
17 memory: "1Gi"
18 cpu: "1000m"
19 env:
20 - name: JAVA_OPTS
21 value: "-XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
22 livenessProbe:
23 httpGet:
24 path: /actuator/health/liveness
25 port: 8080
26 initialDelaySeconds: 60 # ウォームアップ考慮
27 readinessProbe:
28 httpGet:
29 path: /actuator/health/readiness
30 port: 8080
31 initialDelaySeconds: 30