java - java 进程创建处于已删除状态但增加了 linux VM 中的磁盘利用率的 tmp/tmp* 文件
问题描述
我有一个 java spring boot 应用程序,它实现了多线程,其中一个线程订阅 ZMQ,四个并行线程根据一些预定的时间间隔对接收到的数据执行一些处理。当 jar 在 linux VM 上运行并使用命令检查打开的文件时
lsof -s -p<pid>
它显示了一个“tmp/tmp* ... (deleted)”类型的文件,其磁盘利用率呈指数增长,并且进程树显示该文件属于正在运行的 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 进程的命令涉及标准输出的“nohup”和“tee”。有问题的 /tmp/ 中的输出取决于进程接收到的数据(非常庞大),因此日志开始打印在 /tmp/ 以及属性文件中配置的日志目录中。简单地重定向java进程的stdout和stderr就解决了这个问题。
正确命令示例:
nohup java jar <jar name> 2>&1 > dev/null &
推荐阅读
- javascript - 从 odoo 的 pdf_viewer 小部件中删除下载按钮
- sql - 我可以使用文本框引用来选择 MS Access 中的特定记录吗
- java - 菜单项的标题未显示
- c++ - 如何获取QSplitter的初始状态
- python - python选择资源管理器文件
- c++ - 有没有办法在不使用嵌套循环的情况下打印以下模式?
- c# - .NET NpgSQL 将组 array_agg 和 unnest SQL 转换为 LINQ
- php - WooCommerce:从任何上下文保存/更新订单后的挂钩
- sql - 如何将 SQL 中的记录 blob 字段插入 Paradox 表?
- ssh - 使用 SSH 连接到 Web 主机