我安装了最新版本的 cplex,并通过它的 JAVA API 使用它。为了避免构建 cplex 实例的开销,我使用 cplex.clearmodel 然后创建新模型。
但是当我用它做数千次线性规划时,内存泄漏问题非常严重。它消耗了超过 2GB 的 RAM。是否存在任何解决方案来缓解内存泄漏问题?
我安装了最新版本的 cplex,并通过它的 JAVA API 使用它。为了避免构建 cplex 实例的开销,我使用 cplex.clearmodel 然后创建新模型。
但是当我用它做数千次线性规划时,内存泄漏问题非常严重。它消耗了超过 2GB 的 RAM。是否存在任何解决方案来缓解内存泄漏问题?
我之前在运行线性程序时遇到过这个问题。您必须只创建一个对象并继续只使用对该对象的一个引用。
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);
}
}
}
这个问题是
IloCplex cplex = new IloCplex();
在你的程序中只调用一次上面的行。如果 clearModel 方法不起作用,请清除所有约束、清除目标函数并单独清除切割,然后重置约束和目标函数,但不要创建新对象。这就是导致内存泄漏的原因。要解决您的新模型,请使用
cplex.solve()
我想你的代码看起来像这样
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");
}
}
}
创建 IloCplex 对象的实例后,启动 for 或 while 循环。所以,与上面的代码相比,做
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(),这样可以节省大量内存。
对于 CPLEX 20.1,仅调用 IloCplex.end() 对我们来说是不够的。我们需要 IloCplex.endModel() 和 IloCplex.end() 的组合(按此顺序)。
通过 System.gc() 调用垃圾学院也有效,但会显着降低性能。