简体   繁体   English

在JAVA中使用cplex时如何避免内存泄漏?

[英]How to avoid memory leak when using cplex in JAVA?

I install the latest version of cplex, and use it via its JAVA API.我安装了最新版本的 cplex,并通过其 JAVA API 使用它。 To avoid the overhead of constructing cplex instance, I use cplex.clearmodel and then create the new model.为了避免构建 cplex 实例的开销,我使用 cplex.clearmodel 然后创建新模型。

But when I use it to do linear programming thousands of times, the memory leak issue is very serious.但是当我用它做数千次线性规划时,内存泄漏问题非常严重。 It consumed more than 2GB RAM.它消耗了超过 2GB 的 RAM。 Does there exist any solution to alleviate the memory leak issue?是否存在任何解决方案来缓解内存泄漏问题?

I've encountered this issue before when running my linear programs. 在运行线性程序之前,我曾遇到此问题。 You must CREATE exactly one object and continue to use only one reference to that object. 您必须完全创建一个对象,并继续仅使用对该对象的一个​​引用。

import ilog.concert.*; 
import ilog.cplex.*; 
static public class Application { 
    static public main(String[] args) { 
       try {
         IloCplex cplex = new IloCplex(); 
         // create model and solve it 
       } catch (IloException e) { 
          System.err.println("Concert exception caught: " + e); 
       }
     }
   }

This issue is 这个问题是

IloCplex cplex = new IloCplex(); 

Only call the above line once in your program. 在程序中只调用一次以上行。 If the clearModel method isn't working, clear all your constraints, clear your objective function, and clear your cuts individually and then reset your constraints and objective function, but do not create a new object. 如果clearModel方法不起作用,请清除所有约束,清除目标函数,并分别清除剪切,然后重设约束和目标函数,但不要创建新对象。 That is what is causing the memory leak. 这就是导致内存泄漏的原因。 To solve your new model, use 要解决您的新模型,请使用

cplex.solve()

I imagine your code looks something like this 我想你的代码看起来像这样

import ilog.concert.*; 
import ilog.cplex.*; 
public class Example { 
public static void main(String[] args) { 
    try { 
      for(int i = 1;i <= 5;i++){ // Loop with indices that you may use to create your constraints and objective function.
      IloCplex cplex = new IloCplex(); // Cause of memory leak
      double[]    lb = {0.0, 0.0, 0.0}; 
      double[]    ub = {40.0, Double.MAX_VALUE, Double.MAX_VALUE}; 
      IloNumVar[] x  = cplex.numVarArray(3, lb, ub); 
      double[] objvals = {1.0, 2.0, 3.0}; 
       cplex.addMaximize(cplex.scalProd(x, objvals)); 
      cplex.addLe(cplex.sum(cplex.prod(-1.0, x[0]), 
                            cplex.prod( 1.0, x[1]), 
                            cplex.prod( 1.0, x[2])), 20.0); 
      cplex.addLe(cplex.sum(cplex.prod( 1.0, x[0]), 
                            cplex.prod(-3.0, x[1]), 
                            cplex.prod( 1.0, x[2])), 30.0); 
      if ( cplex.solve() ) { 
        cplex.out().println("Solution status = " + cplex.getStatus()); 
        cplex.out().println("Solution value  = " + cplex.getObjValue());
        double[] val = cplex.getValues(x); 
        int ncols = cplex.getNcols(); 
        for (int j = 0; j < ncols; ++j) 
           cplex.out().println("Column: " + j + " Value = " + val[j]); 
      }
      cplex.end(); 
    }
    }
    catch (IloException e) { 
System.err.println("Concert exception '" + e + "' caught"); 
    }
  }
}

Start your for or while loops after you create your instance of the IloCplex object. 创建IloCplex对象的实例后,启动for或while循环。 So, in contrast to the code above, do 因此,与上面的代码相反,

IloCplex cplex = new IloCplex(); // Cause of memory leak
for(int i = 1;i <= 5;i++){ // Loop with indices that you may use to create your constraints and objective function.

根据我对CPLEX 12.7的评估,可以在cplex.end()之后调用system.gc(),这样可以节省大量内存。

For CPLEX 20.1 only calling IloCplex.end() was not enough for us.对于 CPLEX 20.1,仅调用 IloCplex.end() 对我们来说是不够的。 We needed the combination of IloCplex.endModel() and IloCplex.end() (in that order).我们需要 IloCplex.endModel() 和 IloCplex.end() 的组合(按此顺序)。

Invoking the garbage college via System.gc() works also but reduces the performance significantly.通过 System.gc() 调用垃圾学院也有效,但会显着降低性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM