【问题标题】:Memory Cleanup in OSGiOSGi 中的内存清理
【发布时间】:2016-07-29 12:45:50
【问题描述】:

我正在学习 OSGi,因为它现在变得很流行。我使用 linux 作为我的操作系统,使用 OpenJDK 作为开发环境。我在 OSGi Equinox 框架中创建了几个捆绑包 A、B、C.. 等。

我使用以下命令运行 OSGi 框架:

java -jar osgi-3.10.0-v20140606-1445.jar -console

现在我在 OSGi 控制台中安装并启动了 A、B、C .. 等包。使用 linux top 命令我观察到内存和 CPU 利用率如下:

 PID   PPID USER     STAT   VSZ %VSZ %CPU COMMAND
 1972   422 root     S     368m  74%   3% java -jar osgi-3.10.0-v20140606-1445.jar -console

我观察到我的捆绑包中的一个说 B 导致内存利用率很高。我从 OSGi 卸载了 bundle B 并再次检查了内存使用情况。我发现相同的结果,无论是 CPU 使用率还是内存使用率都没有变化。

我在没有捆绑 B 的情况下重新启动了 OSGi 框架,然后我发现了以下统计信息

1972   422 root     S     214m  43%   0% java -jar osgi-3.10.0-v20140606-1445.jar -console

因此,在此之后,我知道从 OSGi 卸载包 B 并没有更新内存或 CPU 使用率,直到我重新启动 OSGi 框架。

所以有人可以建议我,我如何在 OSGi 中卸载捆绑包后清理内存。

【问题讨论】:

  • 插件B关闭时做了什么?你的stop-Method 怎么样?
  • @TMichelsen 我正在插件 B 中执行一些数据库操作。当我停止 B 时,我也关闭了数据库连接和其他资源。 private void closeConnection() 抛出 SQLException { if (sqlConnection == null || sqlConnection.isClosed()) { return; } sqlConnection.close(); sqlConnection = null;运行时 r=Runtime.getRuntime(); r.freeMemory(); r.gc(); }
  • sqlConnection = DriverManager.getConnection(ConfigurationConstants.DATABASE_NAME);这条线导致高内存利用率。我正在使用 sqlite 数据库。
  • @Raj:请不要将代码放入 cmets!改为编辑问题。无论如何,我看不到真正的内存使用情况,只有VSZ 有不同的AFAIK:Virtual Memory Usage from Java under Linux, too much memory used
  • 尝试运行 jvisualvm(在 Java 的 bin 目录中)并在 JVM 上执行 gc。如果没有必要,Java 不会释放内存,即使对象已被清理。执行 GC 后,您可以在 JVisualVM 中看到真实的内存使用情况。 PS 显示的信息没有关于实际 Heap 使用情况的信息。

标签: java osgi iot osgi-bundle


【解决方案1】:

卸载一个包将阻止其他包连接到它(类加载器管理),但它不会从内存中卸载现有实例或停止这些类中的活动。 卸载实例是正常的 Java 垃圾收集过程;您需要确保应用程序中没有其他任何东西持有对实例的引用,然后垃圾收集器将释放实例使用的资源。

【讨论】:

  • 我已经检查过了,当捆绑停止时,我将所有引用设置为 null。
  • 在这种情况下,最好的办法是进行堆转储并找出捆绑中类实例的保留内容。像 Eclipse Memory Analyzer 这样的工具非常适合这个。 (它是对您担心的那个包加载的类的实例的引用,而不仅仅是对包对象的引用。)
  • 出于非常合理的 CPU 优化原因,您的 JVM 垃圾收集器也可能选择不缩小堆大小(您在命令行上看到的),即使占用率较低。
猜你喜欢
  • 2011-08-26
  • 1970-01-01
  • 2021-11-24
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多