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:+UseG1GCZGC(Java 15+)
超低レイテンシ(<10ms)。大容量ヒープ向け。
-XX:+UseZGCShenandoah
低レイテンシ。コンカレントコンパクション。
-XX:+UseShenandoahGC主要なJVMオプション
1 # メモリ設定 2 java -Xms512m -Xmx2g -jar app.jar 3 # -Xms: 初期ヒープサイズ 4 # -Xmx: 最大ヒープサイズ 5 6 # GC設定 7 java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar 8 9 # GCログ出力(Java 9+) 10 java -Xlog:gc*:file=gc.log:time,level,tags -jar app.jar 11 12 # コンテナ対応(Java 10+はデフォルト有効) 13 java -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -jar app.jar 14 15 # JIT最適化ログ 16 java -XX:+PrintCompilation -jar app.jar 17 18 # ヒープダンプ(OOM時) 19 java -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 3 public class Application { 4 public static void main(String[] args) { 5 SpringApplication.run(Application.class, args); 6 } 7 } 8 9 @RestController 10 @RequestMapping("/api/users") 11 public 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 # マルチステージビルド 2 FROM eclipse-temurin:21-jdk AS builder 3 WORKDIR /app 4 COPY . . 5 RUN ./gradlew bootJar --no-daemon 6 7 FROM eclipse-temurin:21-jre 8 WORKDIR /app 9 10 # セキュリティ: 非rootユーザー 11 RUN addgroup --system app && adduser --system --ingroup app app 12 USER app 13 14 COPY --from=builder /app/build/libs/*.jar app.jar 15 16 # JVM設定 17 ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC" 18 19 EXPOSE 8080 20 ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
1 # Kubernetes Deployment 2 apiVersion: apps/v1 3 kind: Deployment 4 metadata: 5 name: java-app 6 spec: 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