当前位置: 首页 > news >正文

JAR文件句柄泄漏问题分析与解决方案

根据堆转储分析截图,我发现了JAR文件句柄泄漏的具体证据。以下是详细分析和解决方案:

堆转储分析结果

关键发现

从堆转储中可以看到:

  • com.gitee.starblues.loader.jar.JarFileWrapper存在大量实例

  • com.gitee.starblues.loader.jar.RandomAccessDataFile占用显著内存

  • java.util.concurrent.ConcurrentHashMap高亮显示,表明可能存在缓存管理问题

根据堆栈分析结果,我发现了一个严重的内存问题。主要内存占用来自插件框架的JAR文件处理和Agent事件系统。

1. 主要内存占用对象

类名实例数浅层大小保留大小问题描述
int[]136,434270.58 MB270.58 MB大量整型数组
PipelineEvent1,048,57650.33 MB50.33 MB事件积压严重
MetricEvent1,048,57650.33 MB50.33 MB事件积压严重
byte[]294,90835.77 MB33.4 MB字节数组缓存
JarFileWrapper36,8504.13 MB310.83 MBJAR文件泄漏
JarFileEntries39,2692.2 MB277.68 MBJAR文件泄漏

2. 核心问题

事件系统积压PipelineEventMetricEvent各有100多万个实例,说明事件生产者速度远超消费者速度。

JAR文件泄漏JarFileWrapperJarFileEntries的保留内存远大于浅层大小,说明存在对象引用链导致无法GC。

问题根因分析

1. JarFileWrapper 实例泄漏

2. RandomAccessDataFile 未正确关闭

查找到jarFileWrapper创建地址

static JarURLConnection get(URL url, JarFile jarFile) throws IOException {// ... 前面的代码 ...JarFileWrapper jarFileWrapper = new JarFileWrapper(jarFile);PluginResourceStorage.addJarFile(jarFileWrapper);System.out.println("brick loader cached jar file "+jarFileWrapper.getUrl().toString());return new JarURLConnection(url, jarFileWrapper, jarEntryName);
}

创建过程:

  1. 将传入的 JarFile对象包装成 JarFileWrapper

  2. 通过 PluginResourceStorage.addJarFile(jarFileWrapper)将包装后的文件添加到资源存储中

  3. 输出日志信息

  4. 使用包装后的 jarFileWrapper创建新的 JarURLConnection对象

这个包装过程主要用于在插件资源存储中管理JAR文件的生命周期,确保在插件卸载时能够正确关闭相关的JAR文件资源。

根据添加日志代码运行记录分析

 System.out.println("brick loader cached jar file "+jarFileWrapper.getUrl().toString());

问题分析

1. 重复JAR文件缓存

从日志中可以看到,同一个JAR文件被重复缓存多次:

  • jjwt-impl-0.11.5.jar被缓存了至少15次

  • jjwt-api-0.11.5.jar被缓存了至少4次

  • classes目录被缓存了至少6次

jar缓存多次原因

  • 每次 URL 连接被创建时,都会调用 PluginResourceStorage.addJarFile

  • 在 PluginResourceStorage.addJarFile 中,会遍历所有已注册的插件 Storage 并添加 JAR 文件

  • 没有去重机制,导致同一个 JAR 文件被重复添加

2. 根本原因

问题出现在 JarURLConnection.get()方法中

JarFileWrapper jarFileWrapper = new JarFileWrapper(jarFile);
PluginResourceStorage.addJarFile(jarFileWrapper);
System.out.println("brick loader cached jar file name="+jarFileWrapper.getName()+" url=" +jarFileWrapper.getUrl().toString());
return new JarURLConnection(url, jarFileWrapper, jarEntryName);

每次调用这个方法都会创建新的 JarFileWrapper实例,但没有检查是否已经存在相同的JAR文件

优化方案:

   在创建JarFileWrapper对象时,先从PluginResourceStorage加载缓存,没有则创建包装类缓存,返回对应包装类

在当前的 PluginResourceStorage.Storage 类设计中,三个 Map 确实存在数据冗余和重复缓存的问题:

当前缓存结构分析

  1. rootJarFileMap:存储文件对象到 JarFileWrapper 的映射

  2. jarFileMap:存储文件名到 AbstractJarFile 列表的映射

  3. jarFileCache:存储文件名到 JarFileWrapper 的映射(新添加的)

存在的问题

  1. 数据冗余:同一个 JarFileWrapper 对象可能同时存在于 jarFileMap 和 jarFileCache 中

  2. 内存浪费:维护多个映射结构增加了内存开销

  3. 一致性风险:多个缓存之间可能存在数据不一致的问题

优化方案

方案1:统一缓存结构

将三个 Map 合并为一个统一的缓存结构:

主要改进:

  1. 统一缓存结构:使用单一的 jarFileCache 映射来存储所有 JAR 文件,避免数据冗余

  2. 辅助映射:使用 fileToNameMap 来支持通过 File 对象查找,保持原有功能

  3. 线程安全:使用 putIfAbsent 确保并发环境下的安全性

  4. 去重机制:自动避免重复缓存相同的 JAR 文件

  5. 简化关闭逻辑:只需要清理一个主缓存和一个辅助映射

  6. 新增调试方法:添加了 getAllCachedJarFiles 方法便于监控缓存状态

问题根因分析:

JarURLConnection和PluginResourceStorage 的修改大大减少了句柄消耗问题。那么问题来了,之前代码在JDK11与JDK17表现完全不一致。之前代码在JDK11时并未出现当前严重的句柄泄漏,但是在JDK17时出现了严重泄漏,具体是什么原因导致的呢?

JDK 11和JDK 17在JAR文件处理和资源管理方面确实有一些重要差异,这解释了为什么在JDK 17中会出现更严重的句柄泄漏问题。

JDK 11 vs JDK 17 的主要差异

1. 模块系统(Module System)的强化

  • JDK 9+引入了模块系统,对类加载和资源访问有更严格的管理

  • JDK 17进一步加强了模块隔离,可能导致资源无法被及时回收

2. 垃圾回收器的改进

  • JDK 17使用G1 GC作为默认回收器,与JDK 11的Parallel GC有不同的内存管理策略

  • G1 GC可能更晚触发Full GC,导致资源句柄保持更长时间

3. JAR文件处理的内部实现变化

  • JDK 17对JarFileJarURLConnection的内部实现可能有优化

  • 可能使用了不同的缓存策略或资源管理机制

针对JDK 17的进一步优化

基于上述分析,我们需要对代码进行进一步优化以适应JDK 17的特性:

增强资源追踪和及时释放

http://www.dtcms.com/a/586769.html

相关文章:

  • 布吉做棋牌网站建设哪家公司便宜开发微信公众
  • 达梦数据库监听进程
  • 五屏网站建设品牌linux下搭建wordpress
  • Falcon-RX PTP交换机
  • 不买域名怎么做网站泰安人才网最新招聘
  • 【每天一个AI小知识】:什么是模型蒸馏?
  • 兰溪市建设局官方网站网站怎么做优化百度能搜索到
  • 如何删除网站的信息吗网页是怎么做的
  • 网站开发费入什么科目专门做民宿的网站有哪些
  • 阳泉建设局网站搜索引擎营销就是seo
  • 网站建设的七个步骤网站如何验证登陆状态
  • 深圳知名网站建设公司主要的网站开发技术路线
  • 做网站用别人的图片泉州网站建设培训
  • 深圳专业英文网站建设建筑人才直聘网
  • 个人网站备案地址选择惠州手工外发加工网
  • 高防服务器在网络游戏中的优势
  • 微商城网站建设策划网站建设简讯
  • 在 Go 语言中,模板字符串
  • PPT导出为图片的格式选择:JPG与PNG的区别
  • 开封网站建设流程与开发步骤免费正版高清素材库
  • K8S第二次安装
  • 手机上怎么上传网站什么是网络营销与策划
  • 港股上市只是起点:张兴海重塑赛力斯战略蓝图
  • JavaScript对DOM文本内容进行瞬间替换分析
  • 大模型领域部分资源平台汇总
  • 用ai来写一个CO2传感器检测
  • 企业网站建设方案策划北京网络运维公司
  • 怎么做网站免费的刷赞dw做网站可以做毕业设计吗
  • 奉城网站建设开发一个网站
  • 芜湖建设厅官方网站公司装修预算表