【问题标题】:How to avoid memory leak when using cplex in JAVA?在 JAVA 中使用 cplex 时如何避免内存泄漏?
【发布时间】:2012-11-17 12:28:32
【问题描述】:

我安装了最新版本的 cplex,并通过其 JAVA API 使用它。 为了避免构建 cplex 实例的开销,我使用 cplex.clearmodel 然后创建新模型。

但是当我用它做数千次线性规划时,内存泄漏问题非常严重。它消耗了超过 2GB 的 RAM。 是否有任何解决方案可以缓解内存泄漏问题?

【问题讨论】:

    标签: java memory-leaks cplex


    【解决方案1】:

    我之前在运行线性程序时遇到过这个问题。您必须只创建一个对象并继续只使用对该对象的一个​​引用。

    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.clearmodel 清除之前的模型。我知道多次创建对象时会出现更多的内存泄漏,但是当我只创建一次模型并使用清除模型创建新模型时仍然存在一些内存泄漏。
    • +1 人,你刚刚救了我,我不知道多少小时。谢谢。我的内存快疯了,现在它不超过 340 MB。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      对于 CPLEX 20.1,仅调用 IloCplex.end() 对我们来说是不够的。我们需要 IloCplex.endModel() 和 IloCplex.end() 的组合(按此顺序)。

      通过 System.gc() 调用垃圾学院也可以,但会显着降低性能。

      【讨论】:

        【解决方案4】:

        【讨论】:

          猜你喜欢
          • 2020-11-13
          • 2010-12-22
          • 1970-01-01
          • 1970-01-01
          • 2020-05-13
          • 1970-01-01
          • 2012-10-22
          相关资源
          最近更新 更多