Last active
October 30, 2024 10:35
-
-
Save kelunik/be51e5e2fdf746bbc86383b922bbb05e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
public class LoggingGCRaceConditionTester { | |
private static final Logger _log = LoggerFactory.getLogger(LoggingGCRaceConditionTester.class); | |
/** | |
* Start with -Xmx2G | |
*/ | |
public static void main( String[] args ) { | |
new LoggingGCRaceConditionTester().test(); | |
} | |
private static void joinQuietly( Thread t ) { | |
try { | |
t.join(); | |
} | |
catch ( InterruptedException e ) { | |
throw new RuntimeException(e); | |
} | |
} | |
private static void setDaemon( Thread t ) {t.setDaemon(true);} | |
private volatile boolean endlessLoop = true; | |
void test() { | |
List<Thread> threads = List.of( // | |
new Thread(this::log, "Logger loop"), // | |
new Thread(this::gc, "GC loop") // | |
); | |
threads.forEach(LoggingGCRaceConditionTester::setDaemon); | |
threads.forEach(Thread::start); | |
threads.forEach(LoggingGCRaceConditionTester::joinQuietly); | |
} | |
private void gc() { | |
try { | |
Thread.sleep(10); // give the log thread a headstart | |
} | |
catch ( InterruptedException e ) { | |
throw new RuntimeException(e); | |
} | |
while ( true ) { | |
Thread.yield(); | |
System.gc(); | |
} | |
} | |
private void log() { | |
long suffix = 0; | |
boolean npe = false; | |
while ( true ) { | |
try { | |
String name = "TestLogger" + (++suffix); | |
try { | |
Logger l = LoggerFactory.getLogger(name); | |
if ( npe || (suffix % 100) == 0 ) { | |
l.info(""); | |
} else { | |
l.trace(""); | |
} | |
} | |
catch ( NullPointerException t ) { | |
_log.warn("{} threw {}: {}", name, t.getClass().getSimpleName(), t.getMessage()); | |
npe = true; | |
} | |
catch ( Throwable t ) { | |
_log.error("{} threw {}: {}", name, t.getClass().getSimpleName(), t.getMessage()); | |
} | |
} | |
catch ( Throwable t ) { | |
_log.error("caught", t); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment