Java Garbage Collection, JVM Memory Model, Concurrency Locks, Thread Pools and Distributed Locking
The article provides a comprehensive overview of Java garbage‑collection algorithms, JVM memory regions, object reachability analysis, the semantics of volatile, synchronized and ReentrantLock, thread‑pool creation and operation, deadlock examples, distributed‑lock strategies, and related tooling such as JUC utilities and Git conflict handling.
This article explains the main garbage‑collection algorithms used by the JVM: the copying algorithm for the young generation, mark‑sweep and mark‑compact for the old generation, and the generational collection strategy that combines them.
Copying algorithm – young generation
Mark‑sweep algorithm – old generation
Mark‑compact algorithm – old generation
Generational collection – small young region with low object survival, large old region with high survival, using a mix of the above algorithms
Object reachability is determined either by reference‑counting (which cannot handle cyclic references) or by reachability analysis starting from GC roots; objects not reachable from any root are considered garbage.
The JVM memory layout consists of the Method Area (class metadata), the Heap (object instances), the Java Virtual Machine Stack (stack frames for each method), the Program Counter (current byte‑code line), and the Native Method Stack.
The volatile keyword provides visibility, does not guarantee atomicity, and prevents instruction reordering.
Differences between synchronized and Lock (java.util.concurrent.locks.ReentrantLock): synchronized is a JVM keyword, automatically releases the lock, is non‑fair, and cannot be interrupted. Lock is an API class, requires explicit lock() and unlock(), can be fair or non‑fair, supports interruptible lock acquisition and timed try‑lock, and allows multiple Condition objects for selective wake‑up.
Optimistic lock relies on version fields and CAS (compare‑and‑swap); pessimistic lock (e.g., synchronized) always acquires a lock before proceeding.
Thread‑pool creation can be done via Executors utilities or directly with ThreadPoolExecutor, which requires seven parameters: corePoolSize, maximumPoolSize, keepAliveTime, time unit, workQueue, threadFactory, and rejection handler.
CPU‑usage troubleshooting steps: use top to find the PID, ps -mp PID -o THREAD,tid,time to locate the hot thread, then jstack PID to dump thread stacks.
Example of a deadlock:
class Lock implements Runnable {
private String lockA;
private String lockB;
public Lock(String lockA, String lockB) { this.lockA = lockA; this.lockB = lockB; }
@Override
public void run() {
synchronized (lockA) {
System.out.println(Thread.currentThread().getName() + " used " + lockA + " trying " + lockB);
try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
synchronized (lockB) {
System.out.println(Thread.currentThread().getName() + " used " + lockB + " trying " + lockA);
}
}
}
}
public class DeadLockDemo01 {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new Lock(lockA, lockB), "T1").start();
new Thread(new Lock(lockB, lockA), "T2").start();
}
}Thread creation methods include extending Thread, implementing Runnable, implementing Callable with FutureTask, and using thread pools. Thread states are: New, Runnable (Ready), Running, Blocked, and Terminated.
Thread‑pool execution flow: initially zero threads; execute() creates core threads up to corePoolSize, then queues tasks; if the queue is full and the pool size is below maximumPoolSize, non‑core threads are created; excess tasks trigger the rejection policy; idle threads beyond corePoolSize are terminated after keepAliveTime.
JVM architecture recap: Method Area, Heap, JVM Stack, Program Counter, Native Method Stack.
Thread‑safe singleton (lazy, double‑checked locking) example:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() {}
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}JUC utilities covered: CountDownLatch, CyclicBarrier, Semaphore, and their basic usage.
Distributed lock implementations include MySQL, Redis (using SETNX with expiration and Lua scripts for atomicity), and Zookeeper; features such as exclusivity, re‑entrancy, dead‑lock avoidance, auto‑renewal, and the RedLock algorithm are discussed.
Git merge conflict causes and resolution: conflicts arise when the same file or filename is modified in different branches; the resolution process is identical regardless of the specific scenario.
Differences among thread control methods: sleep() – pauses the current thread without releasing any held lock. wait() – releases the object's monitor and waits to be notified. yield() – hints that the current thread is willing to let other threads run. join() – causes the calling thread to wait until the target thread finishes. interrupt() – sets the interrupt flag; actual interruption depends on the thread's code. isInterrupted() – checks the interrupt flag without clearing it.
Lock storage details: lock state is kept in the object header's Mark Word; the header also stores hash code and other metadata. In a 32‑bit JVM, each object occupies at least two words (three for arrays).
Fair vs. non‑fair locks: fair locks grant access in FIFO order, while non‑fair locks may allow a thread to acquire the lock out of order, improving throughput but risking starvation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
