代码之家  ›  专栏  ›  技术社区  ›  Anurag Sharma

通过流程识别打开的FileOutputStreams

  •  0
  • Anurag Sharma  · 技术社区  · 4 年前

    随着FileOutputStream打开-关闭差异的数量随着时间的推移而增加,我们的Java应用程序中出现了内存泄漏。在我们的例子中,堆是相当稳定的,但由于FileOutputStreams是开放的,所以我们在JVM本机内存中面临内存泄漏。

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

    0 回复  |  直到 4 年前
        1
  •  2
  •   Ingo Kegel    4 年前

    在JProfiler中,可以找到未关闭的FileOutputStreams的分配点,如下所示:

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

    enter image description here

        2
  •  1
  •   DuncG    4 年前

    在Linux系统上 lsof 将帮助您识别哪些文件句柄处于打开状态,以及您是否识别出可能有助于跟踪代码中未正确关闭资源的位置的名称。

    然而,如果你只是使用一个好的IDE,当资源面临无法关闭的风险时,他们会警告你,有一个更简单的方法。

    例如,Eclipse会在这一行标记一条警告 fis1 可能无法正确关闭:

    FileInputStream fis1 = new FileInputStream(file);
        
    

    ... 如果将警告更改为:

    try(FileInputStream fis2 = new FileInputStream(file)) {
    }
    
        3
  •  0
  •   Vladimir Kondratyev    4 年前

    YourKit profiler会自动查找所有未关闭的文件输入流:

    • 捕获并打开内存快照。

    • 选择“检查”选项卡。

    • 在检查树的“其他内存异常”节点中查找。它包含“尚未完成的非关闭资源”。

    • 进行检查。

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