Heute bekomme ich PermGen OutOfMemory
Fehler.Anmutig stoppen Logback in Container-Umgebung
Analyse gezeigt, dass Nächster GC-Stamm für WebappClassLoader
ist Logback thread:
this - value: org.apache.catalina.loader.WebappClassLoader #4
<- contextClassLoader (thread object) - class: java.lang.Thread, value: org.apache.catalina.loader.WebappClassLoader #4
das ist:
java.lang.Thread#11 - logback-1
Thread-Dump aus Heapdump für diesen Thread:
"logback-1" daemon prio=5 tid=34 WAITING
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
Local Variable: java.util.concurrent.SynchronousQueue$TransferStack$SNode#1
Local Variable: java.util.concurrent.SynchronousQueue$TransferStack#6
at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
Local Variable: java.util.concurrent.SynchronousQueue#6
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
Local Variable: java.util.concurrent.ThreadPoolExecutor#34
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
Local Variable: java.util.concurrent.ThreadPoolExecutor$Worker#11
at java.lang.Thread.run(Thread.java:745)
Ich verwende Tomcat 8 mit Hot Replay-Funktion reloadable="true"
e und externalisiert CLASSPATH
über PreResources
:
<Context docBase="/home/user/devel/app/src/main/webapp"
reloadable="true">
<Resources>
<!-- To override application.properties and logback.xml -->
<PreResources className="org.apache.catalina.webresources.DirResourceSet"
base="/home/user/devel/app/.config"
internalPath="/"
webAppMount="/WEB-INF/classes" />
</Resources>
</Context>
und logback.xml
mit scan="true"
:
<configuration debug="false" scan="true" scanPeriod="5 seconds">
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
...
Nach der Änderung in /home/user/devel/app/.config/logback.xml
Speichern Tomcat 8 erhalten eine Benachrichtigung (Ich bin nicht sicher, was API verwendet, um Änderungen an fs zu überwachen) und das erneute Bereitstellen der Anwendung wurde gestartet. Das passiert vor PermGen OutOfMemory
.
Wie kann ich Logback in Container-Umgebung anmutig stoppen?
Wie zu stoppen "logback-1"
thread?
fand ich ein paar ähnliche Diskussion aber nicht verstehen können, was mit dieser Info zu tun:
- http://logback.10977.n7.nabble.com/How-to-stop-all-appenders-td3023.html
- Do I need to flush events when shutting down using logback?
- Correct way to stop custom logback async appender
- Stopping Logback System for Clean Shutdown
UPDATE Ich spiele mit Heap Dump in visualvm
. Unter Bezugsebene Sprung von schlechten logback-1
thread:
lvl1 = flatten(filter(referees(heap.findObject(0xf4c77610)), "!/WebappClassLoader/(classof(it).name)"))
lvl2 = flatten(map(lvl1, "referees(it)"))
lvl3 = flatten(map(lvl2, "referees(it)"))
verweisen sie auf
ch.qos.logback.core.util.ExecutorServiceUtil$1
von greppen in Logback Quellen für ExecutorServiceUtil
I found changelog entry:
Alle von ch geöffnet Fäden. qos.logback.core.util.ExecutorServiceUtil # THREAD_FACTORY sind jetzt Daemons, die eine Anwendung beim Herunterfahren behoben, wenn LoggerContext # stop() wird nicht aufgerufen (LOGBACK-929). Beachten Sie, dass Daemon-Threads abrupt von der JVM beendet werden, was zu unerwünschten Ergebnissen führen kann, z. B. zu beschädigten Dateien, die von FileAppender geschrieben wurden. Es wird weiterhin dringend empfohlen, dass die Anwendung LoggerContext # stop() (z. B. in einem Shutdown-Hook) auf aufruft, um Appender ordnungsgemäß herunterzufahren.
Ist das richtig, dass in Container-Umgebung Daemon Threads Gefahr sind und zu Speicherlecks führen?
Dank dies auch mein WebappClassLoader Leck behoben haben! – whitestryder