A DESCRIPTION OF THE REQUEST :
java.util.concurrent.locks.ReentrantLock.lock() and java.util.concurrent.locks.ReentrantLock.unlock() generates a lot of garbage in the form of java.util.concurrent.locks.AbstractQueuedSynchronizer$Node objects under heavy lock contention.
Minimizing GC invocations is critical in our financial application. We use both ReentrantLock and ArrayBlockingQueue in our application. This is the major source of garbage generation.
ArrayBlockingQueue suffers from the same problem because it uses ReentrantLock for the internal synchronization.
JUSTIFICATION :
ReentrantLock should be optimized to avoid creating new java.util.concurrent.locks.AbstractQueuedSynchronizer$Node objects by caching and reusing them.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Did not expect that much garbage generated by java.util.concurrent.locks.ReentrantLock.lock() and java.util.concurrent.locks.ReentrantLock.unlock().
ACTUAL -
Huge number of java.util.concurrent.locks.AbstractQueuedSynchronizer$Node objects are generated when calling java.util.concurrent.locks.ReentrantLock.lock() and java.util.concurrent.locks.ReentrantLock.unlock().
---------- BEGIN SOURCE ----------
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Ilya Goberman
*/
public class Test {
public static void main(String[] args) {
final ReentrantLock lock = new ReentrantLock();
startThread(lock);
startThread(lock);
}
private static void startThread(final ReentrantLock lock) {
new Thread(new Runnable(){
public void run() {
while (true) {
lock.lock();
try {
}
finally {
lock.unlock();
}
}
}}).start();
}
}
---------- END SOURCE ----------