【问题标题】:Java memory leak and garbage collection,Java内存泄漏和垃圾收集,
【发布时间】:2012-06-28 17:53:17
【问题描述】:

这个问题让我自己和我的同事都感到困惑。在我编写的程序中,我遇到了内存泄漏。每次迭代都将 var Platform 重新分配给一个新对象。但是由于某种原因,旧平台对象没有被 gc 清理并且经过多次迭代后堆溢出:

你们中的一些人可能意识到这是一个 PSO 算法。但是对于那些没有这个函数的人来说,这个函数必须被评估 1000 次,而且 basicplatform 是一个数据量非常大的对象,所以多个实例最终会导致内存溢出,只是为了提供一点上下文。

错误代码:

public class Fitness implements FitnessFunction{

protected Platform platform;

public Fitness(){

}

public Fitness(Platform platform) {
    this.platform = platform;
}

@Override
public double fitness(Particle p) {

    try {
        platform = new BasicPlatform("testData.csv");
    } catch (Exception e) {
        e.printStackTrace();
    }





    platform.startSimulation();
    double prof = platform.getFitness();
    v.clear();
    if(prof != 0)
    return -prof;
    return 0;
}


}

在对为什么会有泄漏感到困惑之后,我的朋友向我展示了这个解决方案,他之前在类似的情况下使用过这个解决方案:

public class TradingRuleFitness implements FitnessFunction{

protected Platform platform;

public Fitness(){

}

public Fitness(Platform platform) {
    this.platform = platform;
}

@Override
public double fitness(Particle p) {


    Vector<Platform> v = new Vector<Platform>();
    try {
        //platform = new BasicPlatform("testData.csv");
        v.add(new BasicPlatform("testData.csv"));
    } catch (Exception e) {
        e.printStackTrace();
    }



        double prof = v.get(0).getFitness;
        v.clear();
        if(prof != 0)
        return -prof;
        return 0;
    }


}

几乎完全一样,但这次不是重新分配 var 平台,而是在向量内创建一个新对象,并在完成后将其删除。这种方法似乎强制 gc 进行清理。

问题是为什么这种向量方法有效,但不是技术上应该的原始方法,是否有更清洁的解决方案?

p.s 我已经清理了一些不必要的代码,因为问题是关于对象的创建和删除

【问题讨论】:

    标签: java memory-management memory-leaks garbage-collection


    【解决方案1】:

    在第一种情况下,如果您的 Fitness 对象被保留,那么您的 Platform 对象也将作为字段保留。

    在第二种情况下,您的平台保存在一个局部变量中,并在fitness 返回时被丢弃。

    它不一定是一个向量,它可以是一个普通的局部变量。

    尝试删除两个示例中的字段,它应该可以工作。

    【讨论】:

    • 我同意这会起作用,但我不明白为什么 GC 在重新分配旧对象时没有清除它?
    • 如果没有清理它是 a) GC 没有运行 b) 它被保存在其他地方。我建议您获取堆转储并使用内存分析器查看它的保留位置。 JHat 是免费的,但使用起来很痛苦。 YourKit 做得很好(您可以免费使用 2 周)
    【解决方案2】:

    似乎在第一个示例中,您还清除了向量本身的“不必要的代码位”:)

    这样的答案很难给出正确的答案...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 2016-11-02
      • 1970-01-01
      • 2012-01-03
      • 2010-11-07
      • 2011-02-12
      相关资源
      最近更新 更多