Fix excessive thread creation (issue #169) - bounded thread pool
Replace unbounded CachedThreadPool with bounded ThreadPoolExecutor. Problem: CachedThreadPool creates unlimited threads. With many players online and slow DB queries, thread count explodes (25000+ threads observed in issue #169), causing memory leaks and server crashes. Fix: ThreadPoolExecutor with 2 core / 8 max threads, 30s keepalive, 256-task bounded queue, and CallerRunsPolicy for backpressure. When the queue is full, tasks execute on the calling thread instead of creating more threads, providing natural flow control. Closes mlus-asuka/PlayerSync#169 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f37e58be53
commit
87d320c1f4
|
|
@ -57,9 +57,7 @@ import java.nio.file.Path;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@EventBusSubscriber(modid = PlayerSync.MODID)
|
||||
|
|
@ -67,7 +65,20 @@ public class VanillaSync {
|
|||
|
||||
public static void register() {}
|
||||
|
||||
static ExecutorService executorService = Executors.newCachedThreadPool(new PSThreadPoolFactory("PlayerSync"));
|
||||
// FIX: Replace unbounded CachedThreadPool with a bounded ThreadPoolExecutor.
|
||||
// CachedThreadPool creates unlimited threads — with many players and slow DB queries,
|
||||
// thread count can explode to 25000+ causing memory leaks and server crashes.
|
||||
// Bounded pool: 2 core threads, max 8 threads, 30s keepalive, 256-task queue.
|
||||
// If the queue is full, tasks run on the calling thread (CallerRunsPolicy) which
|
||||
// provides natural backpressure instead of creating more threads.
|
||||
static ExecutorService executorService = new ThreadPoolExecutor(
|
||||
2, // core pool size
|
||||
8, // maximum pool size
|
||||
30L, TimeUnit.SECONDS, // idle thread keepalive
|
||||
new LinkedBlockingQueue<>(256), // bounded work queue
|
||||
new PSThreadPoolFactory("PlayerSync"),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy() // backpressure: run on caller thread if queue full
|
||||
);
|
||||
|
||||
// Per-player locks to prevent concurrent save/restore operations (anti-duplication)
|
||||
private static final ConcurrentHashMap<String, ReentrantLock> playerLocks = new ConcurrentHashMap<>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user