Groovy 类没有被收集,但没有内存泄漏的迹象

2024-03-28

我有一个 Java 类,它使用自定义类加载器动态重新加载 groovy 类,并且我看到一些奇怪的行为,某些类没有被收集,但随着时间的推移,它不会泄漏内存(例如,perm gen 不会无限期地继续增长)。

在我的java代码中,我正在加载这样的类(为了简单起见,删除了样板文件):

Class clazz = groovyClassLoader.loadClass(className, true, false, true);
instance = clazz.newInstance();

然后我通过清除类加载器缓存、元注册表等来动态重新加载 groovy 类:

for (Class c : groovyClassLoader.getLoadedClasses()){
     GroovySystem.getMetaClassRegistry().removeMetaClass(c);
}
groovyClassLoader.clearCache();

现在,如果我只是循环这段代码,不断加载然后重新加载我的常规类,我会看到奇怪的行为(我的测试代码实际上只是循环重新加载过程 - 它没有对创建的任何对象等执行任何操作,所以上面代码中的实例只是本地的,所以应该有利于 GC)。

如果我运行它,将 maxpermsize 设置为 128m 然后我会出现泄漏行为并且出现 OOM permgen 错误:

但是,如果我再次运行它并将 maxpermsize 增加到 256m,那么一切都很好,它可以永远运行(此图像是 1 小时,但我已经运行了一夜,进行了数千次重新加载):

有人遇到过类似的行为吗?或者有什么想法吗?同样奇怪的是,在第一个示例中,内存使用量呈阶梯式上升,而不是稳定增加。


您看到的锯齿图案是一直分配和释放内存的典型情况。您添加了代码来清除缓存,但这并不自动意味着该类将被收集。在尝试对寿命较长的对象进行正常垃圾回收之前,JVM 往往会大量增加内存。删除类的次数更少,通常仅在完整的 gc 运行期间进行。这可能会导致恼人的情况,即 permgen 已满,并且抛出 OOME,即使可以收集类。确切的行为似乎因版本而异。

反正。仅仅因为该类不再被引用,并不意味着它会立即被收集。相反,permgen 可能会增长到最大值,然后卸载类。

除了您的 loadClass 调用可能导致创建新类和元类注册表以某种方式引用该类之外,还有更多可能引用的类。例如,Groovy 中的调用点缓存也涉及到类的软引用。如果某些东西被反射调用得足够频繁(Groovy 可能必须这样做),则可能会生成辅助类来加速反射。后一个是由 JDK 完成的,而不是 Groovy。

我必须做一个更正:元类不是真正的类,并且不能采用永久生成。但他们引用了采用 permgen 的类。因此,如果元类被硬引用,则该类将保留。 IBM JDK 中有一个有趣的“功能”,如果一个类被硬引用,它就会认为该类是不可加载的,即使执行该引用的对象本身是软引用的一部分。

为了更完整地解释上述行为,我需要 JVM 的输出来进行类加载和卸载。我假设该应用程序理论上可以在 128MB 中运行。如果您查看 16:17:30 之前的低点和之前的 128MB 图表,您可能会注意到之前的一个并不像另一个那么低。这意味着在该时间点之前的代码确实比之前的时间点卸载了更多的类。 JVM 可以自由决定何时删除某个类,并且并不总是删除理论上可以卸载的所有类。您必须在可以卸载的类和性能之间进行权衡。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Groovy 类没有被收集,但没有内存泄漏的迹象 的相关文章

  • Android Studio - 无法识别的 VM 选项“MaxPermSize=256m”

    我刚刚在 Elementary OS 0 3 Freya 上安装了 Android Studio 并使用终端运行它 然而 在我第一次启动时 显示一条错误消息 Gradle 测试 项目刷新失败 无法启动守护进程 这个问题可能是由 守护进程的配
  • 使用 UIWebView loadRequest 的常规块 56、1024、8、244、24 内存泄漏

    我遇到了内存泄漏 但无法通过泄漏 构建 分析或整体检查来找出如何修复 我有一个非常强烈的想法 这是由于我的 UIWebview 加载 JavaScript 的 loadRequest 命令造成的 但我不知道出了什么问题 这是我的设置 我有一
  • Java,ASM:如何从ASM InsnNode获取操作码名称和TagValue?

    我正在研究一些类文件分析 并且正在研究使用 ASM 来读取类 在 Javap 中 操作码以及 tagName 和 tagValue 是内联打印的 但在每个 AbstractInsnNode 中 我只看到 int 的字段 而不是 tagVal
  • 如何向正在运行的 Linux 进程发送 Ctrl-Break?

    我正在调试在 Sun 的 JDK 1 4 2 18 上运行的应用程序中的内存泄漏 该版本似乎支持命令行参数 XX HeapDumpOnCtrlBreak 这可能会导致 JVM 在遇到控制中断时转储堆 如何将其发送到 Linux 机器上的后台
  • 字符串文字的行为令人困惑

    下面的代码中字符串文字的行为非常令人困惑 我可以理解第 1 行 第 2 行和第 3 行是true 但为什么是第 4 行false 当我打印两者的哈希码时 它们是相同的 class Hello public static void main
  • Android Studio 1.0.1 APK META-INF/DEPENDENCIES 中复制的重复文件

    我安装了 Android Studio 版本 1 0 1 并尝试将我的项目从 eclipse 导入到它 它给了我以下错误 Error Execution failed for task app packageDebug Duplicate
  • “找不到符号”或“无法解析符号”错误是什么意思?

    请解释以下有关 找不到符号 无法解析符号 或 找不到符号 错误 Java 中 的信息 他们的意思是什么 哪些因素会导致它们 程序员如何修复它们 这个问题旨在对 Java 中的这些常见编译错误进行全面的问答 0 这些错误之间有什么区别吗 并不
  • Android文件上传器与服务器端php

    我几个小时以来一直在寻找解决方案 但找不到任何解决方案 基本上 我想从我的 Android 设备上传文件到 http 网站 但是 我不知道如何做到这一点 我在设备上使用java 并且我想在服务器端使用PHP 我只想上传文件 而不是在服务器上
  • Spring - 使用 new 是一种不好的做法吗?

    正在创建对象by hand 即使用new操作员而不是注册Springbean 和使用依赖注入被认为是不好的做法吗 我的意思是 确实Spring IoC容器必须了解应用程序中的所有对象吗 如果是这样 为什么 你希望 Spring 创建 bea
  • Hibernate 在更新集合时删除孤儿

    我发现从 Hibernate 中的集合中删除时 孤立记录不会被删除 我一定是做了一些简单的错误 这是 Hibernate 101 但我找不到它 鉴于以下情况 public class Book ManyToOne NotNull Autho
  • Spring数据异常处理

    我正在使用 Spring Data JPA 开发一个项目 我需要处理 JpaRepository 方法调用中的一些异常 在下面的代码中 我需要拦截主键违规错误 但无法直接捕获异常 就我而言 当发生此类异常时 存储库层 JpaReposito
  • HTML 解析和删除锚标记,同时使用 Jsoup 保留内部 html

    我必须解析一些html并删除锚标记 但我需要保留锚标记的innerHTML 例如 如果我的 html 文本是 String html div p some text a href some link text a p div 现在我可以解析
  • 通常可重用的注释或公共注释?

    有没有常用的注释 类似于 commons lang 如果没有 您是否见过在任何开源应用程序开发中有效使用注释 不是内置注释 的情况 我记得 Mifos 用它来进行交易 Mohan i think 休眠验证器 http www hiberna
  • 如何使用 JAVA 将本地图像而不是 URL 发送到 Microsoft Cognitive Face API

    我正在尝试使用 Microsoft 认知服务的 Face API 我想知道如何通过 Rest API 调用将本地图像发送到 Face API 并使用它请求结果JAVA 有人可以帮我解决这个问题吗 Microsoft 在其网站上提供的测试选项
  • 光线追踪三角形

    我正在用java编写一个光线追踪器 并且我能够追踪球体 但我相信我追踪三角形的方式有问题 据我了解 这是基本算法 首先确定射线是否与plane三角形已打开 剪裁所有点 使它们与三角形位于同一平面上 因此xy以平面为例 根据沿着新平面向任意方
  • 正确使用Optional.ifPresent()

    我正在尝试理解ifPresent 的方法OptionalJava 8 中的 API 我有一个简单的逻辑 Optional
  • 滚动文件实现

    我一直很好奇滚动文件是如何在日志中实现的 如何开始用任何语言创建一个文件写入类 以确保不超过文件大小 我能想到的唯一可能的解决方案是 write method size file size size of string to write i
  • JDBC多线程插入可以吗?

    我目前正在开发一个 Java 项目 我需要准备一个大的 对我来说 mysql 数据库 我必须使用 Jsoup 进行网页抓取并将结果存储到我的数据库中 据我估计 我将大约插入 1 500 000 到 2 000 000 条记录 在我的第一次试
  • Android 中的 RoboSpice 库是什么

    我正在尝试了解 android 中的 RoboSpice 库 我在这里看到了在线文档 https github com stephanenicolas robospice wiki Starter Guide 我尝试过什么 我之前研究过使用
  • 如何将钱兑换成零钱

    尝试将输入的数字转换为 25 美分 50 美分 10 美分和 10 分 有几个问题 public class Coins public static void main String args private int quarters di

随机推荐