1. Lý thuyết và Khái niệm Cơ bản
1.1 Các Khía Cạnh Hiệu Năng
- Thời gian phản hồi (Response Time)
- Thông lượng (Throughput)
- Tải CPU (CPU Load)
- Sử dụng bộ nhớ (Memory Usage)
- Độ trễ mạng (Network Latency)
- Tải I/O (I/O Load)
1.2 Các Yếu Tố Ảnh Hưởng
- Cấu trúc code
- Thuật toán và cấu trúc dữ liệu
- Cấu hình JVM
- Database queries
- Network calls
- File I/O operations
2. Best Practices và Design Patterns
2.1 Code Optimization
// Tối ưu String concatenation
public class StringOptimization {
// Bad practice
public String buildString(List<String> items) {
String result = "";
for (String item : items) {
result += item + ", "; // Creates new String object each time
}
return result;
}
// Good practice
public String buildStringOptimized(List<String> items) {
StringBuilder builder = new StringBuilder();
for (String item : items) {
builder.append(item).append(", ");
}
return builder.toString();
}
}
// Tối ưu Collections
public class CollectionOptimization {
// Initialize with proper size
List<String> list = new ArrayList<>(initialCapacity);
// Use proper collection type
Set<String> uniqueItems = new HashSet<>();
Map<String, Integer> frequencyMap = new HashMap<>();
// Use stream for parallel processing
public long countItems(List<String> items) {
return items.parallelStream()
.filter(item -> item.length() > 5)
.count();
}
}
2.2 Database Optimization
@Repository
public class OptimizedRepository {
// Use proper indexing
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> findByEmail(@Param("email") String email);
// Batch processing
@Modifying
@Query(value = "INSERT INTO users (name, email) VALUES :users", nativeQuery = true)
void batchInsert(@Param("users") List<Object[]> users);
// Pagination
@Query("SELECT u FROM User u")
Page<User> findAllPaginated(Pageable pageable);
}
3. Anti-patterns và Common Pitfalls
3.1 Memory Leaks
public class MemoryLeakExample {
// Memory leak - forgetting to close resources
public void badResourceHandling() {
Connection conn = getConnection();
// Use connection
// Forgot to close
}
// Proper resource handling
public void goodResourceHandling() {
try (Connection conn = getConnection()) {
// Use connection
// Auto-closed by try-with-resources
}
}
}
public class PerformanceAntiPatterns {
// N+1 queries problem
public void nPlusOneProblem() {
List<Order> orders = orderRepository.findAll();
for (Order order : orders) {
// This causes N additional queries
Customer customer = customerRepository.findById(order.getCustomerId());
processOrder(order, customer);
}
}
// Solution: Use JOIN FETCH
@Query("SELECT o FROM Order o JOIN FETCH o.customer")
List<Order> findAllWithCustomers();
}
4. Ví dụ Code Thực tế
4.1 Caching Implementation
@Service
public class CachedUserService {
private final UserRepository userRepository;
private final Cache<String, User> cache;
public CachedUserService() {
this.cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(Duration.ofMinutes(5))
.build();
}
public User getUser(String id) {
return cache.get(id, key -> userRepository.findById(key)
.orElseThrow(() -> new UserNotFoundException(id)));
}
public void invalidateCache(String id) {
cache.invalidate(id);
}
}
4.2 Async Processing
@Service
public class AsyncOrderProcessor {
private final ExecutorService executor;
public CompletableFuture<OrderResult> processOrder(Order order) {
return CompletableFuture.supplyAsync(() -> {
// Validate order
validateOrder(order);
// Process payment
return processPayment(order);
}, executor).thenApplyAsync(paymentResult -> {
// Update inventory
updateInventory(order);
// Return result
return new OrderResult(order, paymentResult);
}, executor);
}
}
5. Use Cases và Scenarios
5.1 High-Load System
@Configuration
public class HighLoadConfig {
@Bean
public ConnectionPool connectionPool() {
return ConnectionPool.builder()
.maxSize(100)
.minIdle(10)
.maxLifetime(Duration.ofMinutes(30))
.build();
}
@Bean
public CacheManager cacheManager() {
return RedisCacheManager.builder(redisConnectionFactory())
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)))
.build();
}
}
5.2 Batch Processing
@Service
public class BatchProcessor {
private static final int BATCH_SIZE = 1000;
public void processBatch(List<Item> items) {
List<List<Item>> batches = Lists.partition(items, BATCH_SIZE);
batches.parallelStream().forEach(batch -> {
try {
processBatchItems(batch);
} catch (Exception e) {
handleBatchError(batch, e);
}
});
}
}
6.1 JVM Tuning
public class JvmConfig {
// Example JVM arguments
// -Xms2g -Xmx2g // Fixed heap size
// -XX:+UseG1GC // Use G1 Garbage Collector
// -XX:MaxGCPauseMillis=200 // Target GC pause time
// -XX:+HeapDumpOnOutOfMemoryError // Create heap dump on OOM
public void configureJvm() {
// Get current memory usage
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
// Log memory stats
log.info("Max memory: {} MB", maxMemory / 1024 / 1024);
log.info("Used memory: {} MB", usedMemory / 1024 / 1024);
}
}
6.2 Database Tuning
@Configuration
public class DatabaseConfig {
@Bean
public HikariDataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
config.setIdleTimeout(300000);
config.setConnectionTimeout(20000);
config.setMaxLifetime(1200000);
return new HikariDataSource(config);
}
}
7. Security Considerations
public class SecureOptimization {
private final RateLimiter rateLimiter;
public Response processRequest(Request request) {
// Rate limiting
if (!rateLimiter.tryAcquire()) {
throw new TooManyRequestsException();
}
// Input validation
validateInput(request);
// Process with timeout
return processWithTimeout(request, Duration.ofSeconds(5));
}
}
7.2 Resource Protection
public class ResourceProtection {
private final Semaphore semaphore;
public void processWithLimits() {
try {
if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
try {
// Process request
processRequest();
} finally {
semaphore.release();
}
} else {
throw new ResourceUnavailableException();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new ProcessingException(e);
}
}
}
8. Testing Strategies
@SpringBootTest
public class PerformanceTest {
@Test
public void loadTest() {
int threadCount = 100;
int requestsPerThread = 1000;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
CountDownLatch latch = new CountDownLatch(threadCount);
Stopwatch stopwatch = Stopwatch.createStarted();
for (int i = 0; i < threadCount; i++) {
executor.submit(() -> {
try {
for (int j = 0; j < requestsPerThread; j++) {
service.processRequest();
}
} finally {
latch.countDown();
}
});
}
latch.await(1, TimeUnit.MINUTES);
stopwatch.stop();
log.info("Total time: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
}
8.2 Monitoring Tests
public class PerformanceMonitor {
private final MeterRegistry registry;
public void recordMetrics(String operation, long duration) {
registry.timer("operation.duration",
"operation", operation)
.record(duration, TimeUnit.MILLISECONDS);
registry.counter("operation.count",
"operation", operation)
.increment();
}
}
9. Monitoring và Troubleshooting
9.1 Metrics Collection
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistry meterRegistry() {
CompositeMeterRegistry registry = new CompositeMeterRegistry();
registry.config()
.commonTags("application", "performance-demo")
.meterFilter(MeterFilter.deny(id -> {
String uri = id.getTag("uri");
return uri != null && uri.startsWith("/admin");
}));
return registry;
}
}
@Aspect
@Component
public class PerformanceLoggingAspect {
@Around("@annotation(LogPerformance)")
public Object logPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
Stopwatch stopwatch = Stopwatch.createStarted();
try {
return joinPoint.proceed();
} finally {
stopwatch.stop();
log.info("Method {} took {} ms",
joinPoint.getSignature().getName(),
stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
}
}
10. References và Further Reading
- Java Performance: The Definitive Guide
- Optimizing Java
- Java Performance Tuning
- High Performance Java Persistence
- Java Concurrency in Practice
- JMeter for load testing
- VisualVM for profiling
- Micrometer for metrics
- Prometheus for monitoring
- Grafana for visualization