【问题标题】:Identify open FileOutputStreams by the process通过进程识别打开的 FileOutputStreams
【发布时间】:2020-07-18 10:26:43
【问题描述】:

我们的 Java 应用程序中存在内存泄漏,因为 FileOutputStream 打开 - 关闭的差异随着时间的推移而增加。在我们的例子中,堆非常稳定,但由于 FileOutputStreams 是打开的,我们面临着 JVM 本机内存中的内存泄漏。

您能否提出一种方法,让我们可以识别代码库中可能导致此泄漏的代码片段。

【问题讨论】:

    标签: java memory-leaks jprofiler yourkit


    【解决方案1】:

    在JProfiler中,你可以像这样找到未关闭的FileOutputStreams的分配点:

    1. 记录分配并拍摄堆快照
    2. 选择 FileOutputStream 的所有实例并创建一个新的对象集
    3. 选择“传出引用”视图
    4. 选择 FileOutputStream 实例的“关闭”字段并调用“应用过滤器->通过限制所选值”,然后在值对话框中选择“false”。
    5. 转到堆遍历器的“分配”视图并检查分配调用堆栈树或分配热点视图。

    【讨论】:

      【解决方案2】:

      在 Linux 系统上,lsof 将帮助您识别哪些文件句柄是打开的,如果您识别出哪些名称可以帮助您追踪代码中没有正确关闭资源的位置。

      但是,如果您只使用一个好的 IDE,因为它们会在资源面临无法关闭的风险时发出警告,那么有一个更简单的方法。

      例如 Eclipse 标记此行并警告fis1 可能无法正确关闭:

      FileInputStream fis1 = new FileInputStream(file);
          
      

      ...如果更改为:

      ,警告将消失
      try(FileInputStream fis2 = new FileInputStream(file)) {
      }
      

      【讨论】:

        【解决方案3】:

        YourKit profiler 自动查找所有未关闭的 FileInputStreams:

        • 捕获并打开内存快照。

        • 选择“检查”选项卡。

        • 在检查树中找到“Other memory oddities”节点。它包含“未关闭的资源等待完成”。

        • 运行检查。

        Profiler 还能够找到未关闭的文件、目录流、在终结器中关闭的流以及许多其他问题。更多详情请访问https://www.yourkit.com/docs/java/help/event_inspections.jsp

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-30
          • 1970-01-01
          • 2011-02-10
          • 2011-09-20
          • 1970-01-01
          • 1970-01-01
          • 2011-04-28
          相关资源
          最近更新 更多