---
description: Java Performance
alwaysApply: false
---

# Java Performance

The JVM is a world-class runtime. Measure first, don't fight it.

## Profile Before Optimizing

```bash
java -XX:StartFlightRecording=filename=recording.jfr,duration=60s -jar app.jar
./asprof -d 30 -f profile.html <pid>  # async-profiler
```

## GC Tuning

- G1GC (default) — good for most workloads
- ZGC (`-XX:+UseZGC -XX:+ZGenerational`) — ultra-low latency
- Set `-Xms` = `-Xmx` for predictable behavior

## Memory Patterns

```java
// Bad: autoboxing in hot loops
for (Integer v : list) { sum += v; }
// Good: primitive streams
long sum = list.stream().mapToLong(Integer::longValue).sum();

// Pre-size collections: new HashMap<>(expectedSize * 4 / 3 + 1)
// Use EnumMap/EnumSet for enum keys
```

## String Optimization

```java
var sb = new StringBuilder(256);
for (var item : items) sb.append(item.name()).append('\n');
```

## Connection Pooling (HikariCP)

Pool size: `core_count * 2` (most apps need 10-20). Set `leak-detection-threshold`.

## Caching (Caffeine)

```java
@Cacheable(value = "users", key = "#id")
public Optional<User> findById(UUID id) { ... }
// Always set maximumSize and expireAfterWrite
```

## JMH Benchmarks

```java
@Benchmark @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS)
public String stringBuilder() {
    var sb = new StringBuilder();
    for (var item : items) sb.append(item);
    return sb.toString();
}
```

## Anti-Patterns

- **Never** optimize without profiling data (JMH or JFR)
- **Never** create threads manually — use ExecutorService or virtual threads
- **Never** unbounded caches — use Caffeine with eviction
