2012-06-27 92 views
0

这个问题让我自己和我的同伙感到困惑。在我写的程序中,我遇到了内存泄漏。 var Platform正在被重新分配到一个新的对象。但由于某种原因,旧的平台对象没有被gc清理,经过许多次迭代后堆溢出:Java内存泄漏和垃圾收集,

你们中的一些人可能会意识到这是一种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; 
} 


} 

被困惑,为什么有泄漏,因为肯定有shoudln't是,我的朋友向我展示了该解决方案,这是他在类似的情况之前使用后:

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进行清理。

问题是为什么这种矢量方法的工作原理,而不是技术上应该和有什么更清洁的解决方案吗?

PS我已经清理的代码unnesscary位,因为这个问题是关于对象的创建和删除

回答

2

在第一种情况下,如果你的健身目标SI保留,所以将你的平台的对象被保留,因为它的字段。

在第二种情况下,您的平台保存在本地变量中,并在fitness返回时丢弃。

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

尝试删除这两个示例中的字段,它应该以任何方式工作。

+0

我同意这可行,但我不明白为什么GC重新分配时没有清除旧对象? –

+0

如果未清理,则可能是a)GC未运行b)将其保存在其他地方。我建议你得到堆转储并使用内存分析器来查看它保留的位置。 JHat是免费的,但使用起来很痛苦。 YourKit做得很好(你可以免费使用它2周) –

0

似乎你也被清除了“代码unnesscary位”为载体本身:)

第一个例子

这将是很难给出一个正确的答案是这样的...