java - 是什么让热部署成为 "hard problem"?

标签 java jvm hotdeploy

在工作中,我们遇到了“PermGen out of memory”异常的问题,团队负责人认为这是 JVM 中的错误 - 与代码的热部署有关。他没有解释很多细节,而是指出热部署是一个“难题”,难到连.NET都做不到。

我发现很多文章从鸟瞰角度解释热部署,但总是缺乏技术细节。谁能指出我的技术解释,并解释为什么热部署是“一个难题”?

最佳答案

当一个类被加载时,关于该类的各种静态数据都存储在 PermGen 中。只要存在对这个 Class 实例的实时引用,就不能对这个 Class 实例进行垃圾回收。

我认为问题的一部分与 GC 是否应该从 perm gen 中删除旧的 Class 实例有关。通常,每次热部署时,都会将新的类实例添加到 PermGen 内存池中,而现在未使用的旧类实例通常不会被删除。默认情况下,Sun JVM 不会在 PermGen 中运行垃圾收集,但这可以通过可选的“java”命令参数来启用。

因此,如果您热部署的次数足够多,您最终将耗尽您的 PermGen 空间。

如果您的 Web 应用在取消部署时没有完全关闭 - 例如,如果它让线程运行 - 那么该 Web 应用使用的所有 Class 实例都将固定在永久代空间。您重新部署,现在将所有这些 Class 实例的另一个完整副本加载到 PermGen 中。您取消部署,线程继续运行,将另一组类实例固定在 PermGen 中。您重新部署并加载一整套网络副本......最终您的 PermGen 会填满。

您有时可以通过以下方式解决此问题:

  • 向最近的 Sun JVM 提供命令参数以在 PermGen 和类中启用 GC。即:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
  • 使用不使用固定大小的 PermGen 或对加载的类执行 GC 的不同 JVM

但这只有在您的 Web 应用程序完全干净地关闭时才会有所帮助,不会留下对该 Web 应用程序的类加载器加载的任何类的任何类实例的实时引用。 p>

由于类加载器泄漏,即使这样也不一定能解决问题。 (在某些情况下还有太多的实习字符串。)

查看以下链接了解更多信息(两个加粗的链接有很好的图表来说明部分问题)。

关于java - 是什么让热部署成为 "hard problem"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/660437/

相关文章:

java - 使用 Selenium WebDriver 处理 Windows NTLM 身份验证

java - 为人工智能创建新的启发式方法

java - 如何分析 native JNI 库

java - Full GC - Sun JVM 运行频率

java - 为什么我的 Jenkins 插件找不到我的 pom.xml 依赖项?

java - 尝试从 Java 代码调用存储的 Oracle 过程时出现 ORA-06550

Java char 数组似乎每个 char 需要超过 2 个字节

java - 如何使jsp中的更改生效

eclipse - Eclipse-> Glassfish将不会增量部署-JBOSS可以