概述
[介绍]
Logger bufferedLogger = Logger.getLogger("dummy_logger");
bufferedLogger.removeAllAppenders();
bufferedLogger.setLevel(Level.INFO);
PatternLayout layout = new PatternLayout(PATTERN_LAYOUT);
DailyRollingFileAppenderappender = new DailyRollingFileAppender(layout,logfile,DATE_PATTERN);
appender.setBufferSize(bufferSize);
appender.setBufferedIO(true);
appender.setThreshold(Level.INFO);
appender.setAppend(true);
appender.activateOptions();
bufferedLogger.addAppender(appender);
Logger bufferedLogger = createBufferedLogger(“1.log”, 2048)’
int sizeEachLog = 1024;
for (inti = 0; i < 100; i++)
{
TimeUnit.SECONDS.sleep(3 );
bufferedLogger. info(
DummyDataCreator. getDummyString
( sizeEachLog, logSeed + Integer
.toString( i) + " : "));
}
1)Log4j – Default | 2) Log4j – BufferedIO Enabled | 3)Log4j 2.0 – beta6 BufferedIO Enabled |
Log4j | Log4j | Log4j |
FileOutputStream 备注:在这里,将沿着JNI->JVM->System Call,一直调用到system call的write方法。均为同步调用。 | BufferedWritter (configurable buffer) | BufferedOutputSteam (configurable buffer) 备注:当达到指定的buffersize时,就沿着调用关系,一直同步调用到system call.
|
N/A | sun.nio.cs.StreamEncoder
备注:StreamEncode有hardcode的8k buffer size. 只有数据达到8k的时候,才触发继续JNI->JVN->SYSTEM CALL. | N/A |
-------------------------------------------------------- Java Native Interface -------------------------------------------------------- JVM -------------------------------------------------------- System Call
|
IO类型 | 描述 | 函数 |
NOTE
|
JAVA IO
| java IO几乎没有使用C标准IO。只有在ZIP相关功能中使用了C标准IO. | 所有Java IO/NIO/NIO2 etc |
KB - JVM - IO - hotspot JVM just use Standard IO a little
|
C标准IO( Standard I/O)
| 对文件描述符的更高级封装。使用了缓存与流的概念。C库中提供了用户空间的缓存(Higher level abstraction on descriptor. Buffer/Stream concept is used. There is user-space buffers provided by the C library.) fflush()方法调用,会将用户空间缓存flush到内核空间。 | fopen/fclose/gets/fgets/puts/fputs/fflush/fseek/etc
|
|
内核IO(Kernel I/O | UNIX I/O) | 写入到内核后(flush后),虽然还没有sync到磁盘中,通过tail -f还是可以看到文件变化。 内核IO有自己的缓存。(Kernel has its own buffer.)
fsync()方法将刷新内核缓存到设备中
| open/close/write/read/flush/seed |
|
设备驱动(Device Driver) | CPU将调用设备驱动程序指令与设备交互( CPU will execute Device Driver instruction to drive the communication with I/O.)
|
|
|
实验 |
参数
|
期望行为
|
备注
|
Java
FileOutputStream
|
无
| 每次写入都能直接文件中看到变化,即使没有flush。 |
call
kernerl
io
function. It will reach kernel buffer directly.
|
Java
BufferedOutputSteam
|
bufsiz-512,
write 256 bytes each time
|
每次达到buffersize都,都能看到文件内容变化
|
log4j 2.0 用的就是这个
|
Java
BufferedWriter
|
bufsiz-512,
write 256 bytes each time
|
即使达到了512,文件中也看不到。直到8k才看到。
|
Just the problem of log4j 1.X.
|
Java
FileChannel
|
direct buffer
|
|
it will invoke kernel I/O write directly. [KB - JVM - IO -
invokation
stack of
FileChannel.write
()
|
C Standard IO
|
bufsiz-512,
write 256 bytes each time
|
每次达到buffersize都,都能看到文件内容变化
|
使用setbuf设置buffer大小
there is lib buffer. But it support setup the buffer size
.
|
C Kernel/Unix IO
|
无
|
每次写入都能直接文件中看到变化,即使没有fsync。
|
write to kernel buffer directly
|
- HotSpot JVM Source Code http://download.java.net/openjdk/jdk6/
- Log4j 1.2.17 source code
- Chapter 13 of <<Operating System>> 9th edition
- Chapter 12 of <<Computer.Systems.A.Programmer_s.Perspective>> 1st edistion
- [KB JVM - IO - call stack of Writer.write()]
- [KB JVM - IO - call stack of OutputSteam.write()]
- [KB JVM - IO - call stack of FileChannel.write()]
- [KB JDK - how BufferdOutputStream.write() work]
- [KB JVM - IO - writing difference between FileOutputstream and BufferedWriter ]
- [KB JVM - IO - Java IO Reading with call stack - FileInputSteam, RandomAccessFile, and FileChannel]
最后
以上就是默默大炮为你收集整理的[实践]Log4j 1.X BufferedIO不工作(<8k时)原因分析, 暨深入探查Java IO Output BufferSize的全部内容,希望文章能够帮你解决[实践]Log4j 1.X BufferedIO不工作(<8k时)原因分析, 暨深入探查Java IO Output BufferSize所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复