当前位置: 首页 > 知识库问答 >
问题:

Web 应用程序中的静态变量是否会导致内存泄漏(以及透视的内存不足)?

惠泳
2023-03-14

静态变量以这样的方式进行垃圾收集:

静态变量由类对象引用,类对象由类加载器引用。所以,静态变量只是在加载了静态字段所在的类的类加载器在java中被垃圾收集时才被垃圾收集。

因此,假设一个web应用程序和Tomcat管理它。在一个特定的应用程序中存在静态变量,该应用程序被多次主动重新部署。

静态变量是否保留在元空间中,因为类加载器在重新部署时尚未进行GC处理?

共有1个答案

公孙阳羽
2023-03-14

关键是:显然,一个类在使用时不能被“垃圾回收”。

但是事情变得特定于实现:当Tomcat重新部署一个应用程序时,这是通过抛出一个现有的类加载器来完成的。Tomcat尽其所能绝对“忘记”旧的类加载器以及它加载的类是合乎逻辑的!

因此,当类装入器变成垃圾时,它装入的所有东西都变成垃圾,也有资格被收集。

并引用他们的文档:

WebappX —为部署在单个Tomcat实例中的每个web应用程序创建一个类加载器。web应用程序的/web-INF/classes目录中所有未打包的类和资源,以及WEB应用程序的/WEB-INF/lib目录下JAR文件中的类和资源,对该WEB应用程序可见,但对其他WEB应用程序不可见。

但是后来发现,整个讨论有点复杂,我建议你从这里和那里开始阅读。

本质上,故事是这样的:重新部署一个应用程序导致丢弃它的类加载器,并创建一个新的类加载器。但是这里仍然有可能产生内存泄漏。

 类似资料:
  • 我知道静态字段会导致内存泄漏,因为它们不会被 GC 处理。 但是,当有一个 Web 应用程序部署在容器(例如 Tomcat)中时,每个应用程序都有自己的 ClassLoader,并且可以取消部署。 我的问题是,垃圾收集器是否声明将要卸载的类的静态成员引用的对象? 最简单的情况是单例(由引用自身的静态变量实现),如果应用程序被取消部署,它会被GCed吗?

  • 我正在调试一个我在Tomcat应用程序中多年来遇到的问题——由于Webapp类加载器无法通过气相色谱重新启动应用程序时导致的内存泄漏。我用JProfiler对堆进行了快照,似乎至少我的一些静态变量没有被释放。 某些类有一个静态 final 成员,该成员在首次加载类时初始化,并且因为它是 final,所以我无法在应用程序关闭时将其设置为 null。 静态最终变量是Tomcat中的反模式,还是我错过了

  • 问题内容: 我正在编写一个测试程序,如下所示: 当用户单击按钮A时,它将打开50个JFrame。 当用户单击按钮B时,它将放置所有通过单击按钮A显示的JFrame。 我发现单击按钮B后内存不会减少。我使用任务管理器(在Windows中为+ + ,并检查“ java”的内存使用情况)确定了这一点。 问题答案: 是的,没有办法,无法解决(不仅在Java PL中), 1)实际上,不要在运行时/运行时创建

  • 我有一个运行在Tomcat7上的Java web应用程序出现内存泄漏。在负载下(使用JConsole确定),应用程序的平均内存使用量随时间线性增加。在内存使用达到稳定期后,性能会显著下降。响应时间从大约100ms到[300ms,2500ms],所以这实际上导致了真正的问题。 使用VisualVM,我看到至少一半的内存被字符数组(即char[])使用,而且大多数字符串(每个实例的数量大致相同,为30

  • 问题内容: 如果我的应用程序具有太多的静态变量或方法,则按照定义,它们将存储在堆中。如果我错了请指正我 1)这些变量会在应用程序关闭之前一直在堆上吗? 2)他们随时可以用于GC吗?如果不能,那是内存泄漏吗? 问题答案: 静态方法只是方法,它们不存储在堆中,只是不使用“ this”参数。 静态变量充当GC的“根”。结果,除非您将它们显式设置为null,否则它们将一直存在,只要程序处于活动状态,那么它

  • 我想首先说,这是我第一次必须处理性能,因为这是我第一次开发一个android应用程序。 该应用程序是一个源代码编辑器,在这里你可以打开文件,修改它们,并将它们保存回来。该应用程序由4个部分组成: 导航器视图:包含打开文件的ListView和打开文件夹的TreeView。 代码视图容器:它保存包含实际代码的视图。 代码容器:这是一个小视图,包含一个文本视图和一个自定义EditText(由我扩展Edi