【问题标题】:Declaring static method in Singleton spring bean在 Singleton spring bean 中声明静态方法
【发布时间】:2013-02-15 19:53:24
【问题描述】:

我们遇到了内存泄漏问题,我们怀疑下面的代码可能是原因,我们在单例类中有一个静态方法,并且怀疑它在直接引用时会导致内存泄漏。

// This class is wired in spring xml and loaded as spring bean
public class SpringSingletonRestClient{

// instance method to make a web-service call
public ServiceResponse getResponseFromARestService(String RequestParam){.....}

// public static helper bean mapping method, that is used outside this class 
// for converting the service response object to different object
public static DomainResponse convertServiceResponseToDomainResponse(ServiceResponse serviceResponse){ //conversion logic.... }
 }

}

用法

Class MainClass {

//injected as spring bean
SpringSingletonRestClient client;

public void someMethod(){
ServiceResponse serviceResponse = client.getResponseFromARestService(...);
DomainResponse domainResponse =  SpringSingletonRestClient.convertServiceResponseToDomainResponse(serviceResponse);
// use domainResponse object
.......
.......
}

}

请让我知道是否需要更多说明,因为我刚刚添加了伪。 我们正在运行到高内存使用率,我们怀疑使用在由 spring 启动的类中声明的静态方法没有正确收集垃圾,并且因此发生内存泄漏。

问题 - 在 Spring 启动的单例类中使用静态方法是否很糟糕,即使该静态方法被直接引用使用而不被其实例变量使用。

【问题讨论】:

  • 我不明白为什么使用静态方法会导致泄漏,但我应该承认,当类是单例时,假定它永远不应该被收集(如果你期望的话)跨度>
  • 是的,我怀疑这一点,但在我找到根目录之前不太确定。

标签: java spring static singleton static-methods


【解决方案1】:

静态方法不应导致内存泄漏。它只是意味着该方法不使用任何类字段,并且可以在没有类实例的情况下调用。 Java Documentation 解释了这一点 - 检查类方法部分

通常会发生内存泄漏,因为“全局”字段保留引用并且永远不会停止使用它。这可能是一个集合。您应该使用 JConsole 之类的东西来分析内存使用情况并列出最常用的对象。这应该可以帮助您缩小范围。

编辑(更多信息):您正在调用静态方法而不初始化对象。即任何地方都没有new SpringSingletonRestClient()

DomainResponse domainResponse =  SpringSingletonRestClient.convertServiceResponseToDomainResponse(serviceResponse);

在上述行中,弹簧是无关紧要的。就好像该方法是过程语言中的一个简单函数。因此,这不会导致内存泄漏。

【讨论】:

  • 问题长期出现,不会马上增加cpu使用率,但需要一段时间。我们有 new-relic 定期分析我们的生产使用情况,我们可以看到这个方法被同时调用了几次,当 GC 运行时,堆被清除,但 cpu 内存使用量不断增加并定期崩溃。这表明堆外有东西泄漏。
  • 我同意静态方法,但我怀疑这个静态方法是在由 spring 管理的单例类中。如果 GC 没有选择它。仍然内存泄漏对我来说还没有任何意义。我会运行 JConsole 看看,谢谢你的建议。
  • 我们说的是cpu使用还是mem使用?至于内存的使用,我在答案中提供了更多信息,说明为什么静态方法不能成为罪魁祸首。
  • 谢谢!这对我来说很有意义。由于我们还不能确定这个问题,我们决定将这个类之外的静态方法移到一个不是由 spring 启动的辅助类中。然后我们将运行模拟相同用法的负载测试。如果我们发现任何差异,将更新。但我同意你的回答,那是我完全困惑和不确定的地方。
猜你喜欢
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 2012-09-14
  • 2013-02-26
  • 2014-05-12
  • 2016-12-14
  • 2012-07-05
  • 1970-01-01
相关资源
最近更新 更多