繁体   English   中英

java 进程创建 tmp/tmp* 文件,这些文件处于已删除状态,但会增加 linux VM 中的磁盘利用率

[英]java process creating tmp/tmp* files that are in deleted state but increasing the disk utilization in linux VM

我有一个 java spring boot 应用程序,它实现了多线程,其中一个线程订阅 ZMQ,四个并行线程根据一些预定的时间间隔对接收到的数据执行一些处理。 当 jar 在 linux VM 上运行并使用命令检查打开的文件时

lsof -s -p<pid>

它显示了一个类型为“tmp/tmp* ...(已删除)”的文件,其磁盘利用率呈指数增长,进程树显示该文件属于正在运行的 java 进程。 此问题仅在 linux VM 环境中遇到,在 linux 主机上不会遇到。

应用程序代码没有任何文件被删除而不关闭的情况。 下面是使用文件处理的代码片段:

File file = null;
        PrintWriter printWriter = null;
        BufferedReader br = null;
        FileReader fileReader = null;
        FileWriter fileTruncateObject = null;
try {
                    file = new File(filePath);
                    printWriter = new PrintWriter(file);
                    for (T obj : list) {

                        String jsonString = writeJsonString(obj);
                        if ((jsonString.getBytes().length + file.length()) < 123) {
                            printWriter.write(jsonString);
                            printWriter.flush();

                        }

                        if ((jsonString.getBytes().length + file.length() >= 123) {
                            printWriter.close();
                            fileReader = new FileReader(file);
                            br = new BufferedReader(fileReader);
                            String data = br.readLine();
                            // do something with data
                            br.close();
                            fileReader.close();
                            // file reading successfull, now truncating the file and opening new printwriter object!
                            fileTruncateObject = new FileWriter(file, true);
                            fileTruncateObject.close();
                            printWriter = new PrintWriter(file);
                        }

                    }
                } finally {
                    if (printWriter != null) {
                        printWriter.close();
                    }
                    if (br != null) {
                        try {
                            br.close();
                        } catch (IOException e) {

                        }
                    }
                    if (fileReader != null) {
                        try {
                            fileReader.close();
                        } catch (IOException e) {

                        }
                    }
                    if (file.exists()) {
                        try {
                            if (file.delete()) {
                                //
                            }
                        } catch (Exception e) {
                        }
                    }
                }

此外,该应用程序使用TimeBasedRollingPolicy ,最大大小为 10 MB,最大历史记录为 15 天,具有以下属性:

logging.pattern.console= %d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n
logging.pattern.file= %d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n
logging.level.com.*=DEBUG
logging.path=logs
logging.file=${logging.path}//a.%d.log
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy
logging.file.max-size=10MB
logging.file.max-history=15 

我无法读取文件的内容,因为它处于删除阶段。 此外,它指向“2u”文件描述符。 可能在/tmp文件中写入的过程中发生了一些错误,但我怎么知道错误是什么以及这些错误背后的原因是什么? 有什么办法可以避免创建这个/tmp文件,或者有什么方法可以读取这个文件的内容吗?

用于在 linux VM 中运行 java 进程的命令涉及 stdout 的“nohup”和“tee”。 有问题的 /tmp/ 中的输出取决于进程接收的数据(非常庞大),因此日志开始打印在 /tmp/ 以及在属性文件中配置的日志目录上。 简单地重定向java进程的stdout和stderr就解决了这个问题。

正确命令示例:

nohup java jar <jar name> 2>&1 > dev/null &

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM