java Log4j 挂起我的应用程序我做错了什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/634102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Log4j is hanging my application what am I doing wrong?
提问by Paul Whelan
First some background on the application. I have an application processing many independent tasks in parallel via a thread pool. The thread pool is now hanging.
首先是应用程序的一些背景。我有一个应用程序通过线程池并行处理许多独立的任务。线程池现在挂了。
The following is an snippet from my thread dumps, all my Threads in pool-2 are BLOCKED by "pool-2-thread-78". It seems to be locked trying to write to the console which I find extremely odd. Can anyone shed any light on the situation for me?
以下是我的线程转储的片段,我在 pool-2 中的所有线程都被“pool-2-thread-78”阻塞。它似乎被锁定试图写入我觉得非常奇怪的控制台。任何人都可以为我解释这种情况吗?
EDIT: Platform details java version "1.6.0_07" Java(TM) SE Runtime Environment (build 1.6.0_07-b06) Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
编辑:平台详细信息 java 版本“1.6.0_07”Java(TM) SE 运行时环境(构建 1.6.0_07-b06)Java HotSpot(TM)客户端 VM(构建 10.0-b23,混合模式,共享)
Ubuntu Linux server dual quad core machine.
Ubuntu Linux 服务器双四核机器。
It seems to lock when writing to the printstream, I have considered just removing the console appender however I would rather know why it is blocking and remove it based on this knowledge. In the past the remove and see if it works has come back to bite me :)
它似乎在写入打印流时锁定,我考虑过只删除控制台附加程序,但是我宁愿知道它为什么会阻塞并根据这些知识将其删除。过去删除并查看它是否有效已经回来咬我:)
relevant section from my log4j
我的 log4j 中的相关部分
log4j.rootLogger=DEBUG, STDOUT log4j.logger.com.blah=INFO, LOG log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.LOG=org.apache.log4j.FileAppender
log4j.rootLogger=DEBUG, STDOUT log4j.logger.com.blah=INFO, LOG log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.LOG=org.apache.log4j.FileAppender
Thread dump extract
线程转储提取
"pool-2-thread-79" Id=149 BLOCKED on org.apache.log4j.spi.RootLogger@6c3ba437 owned by "pool-2-thread-78" Id=148 at org.apache.log4j.Category.callAppenders(Category.java:201) at org.apache.log4j.Category.forcedLog(Category.java:388) at org.apache.log4j.Category.error(Category.java:302) at com.blah.MessageProcessTask.run(MessageProcessTask.java:103) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask/java:268) at java.util.concurrent.FutureTask.run(FutureTask/java:54) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619)
"pool-2-thread-78" Id=148 RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:260) at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105) - locked <0x6f314ba4> (a java.io.BufferedOutputStream) at java.io.PrintStream.write(PrintStream.java:430) - locked <0xd5d3504> (a java.io.PrintStream) at org.apache.log4j.ConsoleAppender$SystemOutStream.write(ConsoleAppender.java:173) at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202) at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272) at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276) at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122) - locked <0x6243a076> (a java.io.OutputStreamWriter) at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212) at org.apache.log4j.helpers.QuietWriter.flush(QuietWriter.java:57) at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:315) at org.apache.log4j.WriterAppender.append(WriterAppender.java:159) at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230) - locked <0x45dbd560> (a org.apache.log4j.ConsoleAppender) at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65) at org.apache.log4j.Category.callAppenders(Category.java:203) - locked <0x6c3ba437> (a org.apache.log4j.spi.RootLogger) at org.apache.log4j.Category.forcedLog(Category.java:388) at org.apache.log4j.Category.error(Category.java:302) at com.blah.MessageProcessTask.run(MessageProcessTask.java:103) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask/java:268) at java.util.concurrent.FutureTask.run(FutureTask/java:54) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619)
"pool-2-thread-79" Id=149 BLOCKED on org.apache.log4j.spi.RootLogger@6c3ba437 由 "pool-2-thread-78" Id=148 在 org.apache.log4j.Category.callAppenders( Category.java:201) 在 org.apache.log4j.Category.forcedLog(Category.java:388) 在 org.apache.log4j.Category.error(Category.java:302) 在 com.blah.MessageProcessTask.run(MessageProcessTask.run(MessageProcessTask) .java:103) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask/java:268) 在 java.util.concurrent。 FutureTask.run(FutureTask/java:54) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 在 java .lang.Thread.run(Thread.java:619)
"pool-2-thread-78" Id=148 RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:260) at java.io.BufferedOutputStream.write(BufferedOutputStream) .java:105) - 在 java.io.PrintStream.write(PrintStream.java:430) 锁定 <0x6f314ba4>(一个 java.io.BufferedOutputStream) - 在 org.apache 锁定 <0xd5d3504>(一个 java.io.PrintStream) .log4j.ConsoleAppender$SystemOutStream.write(ConsoleAppender.java:173) at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202) at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272) at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276) at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122) - 在 java 上锁定 <0x6243a076> (a java.io.OutputStreamWriter)。io.OutputStreamWriter.flush(OutputStreamWriter.java:212) at org.apache.log4j.helpers.QuietWriter.flush(QuietWriter.java:57) at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:315) at org .apache.log4j.WriterAppender.append(WriterAppender.java:159) at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230) - 锁定 <0x45dbd560> (a org.apache.log4j.ConsoleAppender) 在 org. apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65) at org.apache.log4j.Category.callAppenders(Category.java:203) - 锁定 <0x6c3ba437> (a org.apache.RootLog4j).spi在 org.apache.log4j.Category.forcedLog(Category.java:388) 在 org.apache.log4j.Category.error(Category.java:302) 在 com.blah.MessageProcessTask.run(MessageProcessTask.java:103) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask/java:268) 在 java.util.concurrent.FutureTask.run (FutureTask/java:54) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 在 java.lang。 Thread.run(Thread.java:619)[907] 第907话[907] 第907话
采纳答案by siddhadev
You could use the AsyncAppender to better detach the logger from the appenders.
您可以使用 AsyncAppender 更好地将记录器与附加程序分离。
On Windows, if you click in the console window, this will pause the console, e.g. the stdout buffer will fill up, and as the console appender writes serially, your application will hang until you release the console (press enter or so).
在 Windows 上,如果您在控制台窗口中单击,这将暂停控制台,例如 stdout 缓冲区将填满,并且随着控制台附加程序串行写入,您的应用程序将挂起,直到您释放控制台(按 Enter 左右)。
Consider using AsyncAppender with log4j - most of the time it is good idea - the only problem beeing - the AsynAppender buffer is not flushed completely on exit.
考虑将 AsyncAppender 与 log4j 一起使用 - 大多数时候这是个好主意 - 唯一的问题是 - AsynAppender 缓冲区在退出时没有完全刷新。
回答by siddhadev
first, i believe log4j writes to files and the console serially or else all your logs would be corrupted. so while one thread is writing another thread that wants to write has to wait until the other one is finished. also, stdout can block if whatever is attached to it on the other end is not draining it.
首先,我相信 log4j 会串行写入文件和控制台,否则您的所有日志都会被破坏。因此,当一个线程正在写入另一个想要写入的线程时,必须等到另一个线程完成。此外,如果另一端连接到它的任何东西没有耗尽它,stdout 可以阻塞。
in unix there is a special file descriptor called stdout. when you start applications in the console stdout will be attached to the console. you can also redirect stdout to other files. ex: java Blah > /dev/null. chances are you have stdout pointing to a file that is filling up. for example a pipe is a file and if the program at the other end isn't draining the pipe then the program that is writing to the pipe will eventually block.
在 unix 中有一个称为 stdout 的特殊文件描述符。当您在控制台中启动应用程序时,stdout 将附加到控制台。您还可以将标准输出重定向到其他文件。例如:java Blah > /dev/null。很可能你的标准输出指向一个正在填满的文件。例如,管道是一个文件,如果另一端的程序没有排空管道,那么写入管道的程序最终将阻塞。

