代码之家  ›  专栏  ›  技术社区  ›  Chris

OutOfMemoryError:GC开销限制超过标准

  •  2
  • Chris  · 技术社区  · 7 年前

    Criterium 图书馆表达式为

    (vec (range 10000000))
    

    要对其进行基准测试,请键入

     (criterium.core/bench (vec (range 10000000)))
    

    过了一段时间,我

     OutOfMemoryError GC overhead limit exceeded  java.lang.Long.valueOf (Long.java:840)
    

    正如我所见 here 这意味着堆的最大大小(1 GB)不足以容纳数据,垃圾收集器尝试释放空间,但无法做到这一点。然而,像下面这样对表达式进行微标记并不会产生这种错误

    (dotimes [i 60] (time (vec (range 10000000))))
    

    here 那就是 bench

    编辑: 启动新的repl时,请输入以下代码

    {:max (.maxMemory (Runtime/getRuntime)), :total (.totalMemory (Runtime/getRuntime))}
    

    输出

    {:max 922746880, :total 212860928}
    

    在我跑步之后 (dotimes [i 60] (time (vec (range 10000000)))) (criterium.core/bench (vec (range 10000000)))

    it输出

    {:max 922746880, :total 922746880}
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Minh Tuan Nguyen    7 年前

    通过这个测试,我能够重现这种行为:

    ;project.clj
    :profiles {:test    {:jvm-opts ["-Xms1024m" "-Xmx1024m"]}}
    
    (:require [clojure.test :refer :all]
              [criterium.core :as ben])
    
    (deftest ^:focused ben-test
      (is (ben/with-progress-reporting
            (ben/bench (vec (range 10000000))))))
    

    堆栈跟踪如下所示:

    Estimating sampling overhead                                         
    Warming up for JIT optimisations 10000000000 ...                     
    compilation occurred before 377618 iterations                      
    ...
    
    Estimating execution count ...
    Sampling ...
    Final GC...
    Checking GC...
    Finding outliers ...
    Bootstrapping ...
    Checking outlier significance
    Warming up for JIT optimisations 10000000000 ...
    compilation occurred before 1 iterations
    
    criterium.core$execute_expr_core_timed_part$fn__40395.invoke (core.clj:370)                                                                                                                                                                                                        
    criterium.core$execute_expr_core_timed_part.invokeStatic (core.clj:366)                                                                                                                                                                                                            
    criterium.core$execute_expr_core_timed_part.invoke (core.clj:345)                                                                                                                                                                                                                  
    criterium.core$execute_expr.invokeStatic (core.clj:378)                                                                                                                                                                                                                            
    criterium.core$execute_expr.invoke (core.clj:374)                                                                                                                                                                                                                                  
    criterium.core$warmup_for_jit.invokeStatic (core.clj:428)                                                                                                                                                                                                                          
    criterium.core$warmup_for_jit.invoke (core.clj:396)                                                                                                                                                                                                                                
    criterium.core$run_benchmark.invokeStatic (core.clj:479)                                                                                                                                                                                                                           
    criterium.core$run_benchmark.invoke (core.clj:470)                                                                                                                                                                                                                                 
    criterium.core$benchmark_STAR_.invokeStatic (core.clj:826)                                                                                                                                                                                                                         
    criterium.core$benchmark_STAR_.invoke (core.clj:812) 
    

    执行expr核心定时部分 (核心clj:345)。此函数执行表达式 n次,并将每次返回的值保存到所谓的可变位置。我的假设是我们这里有内存泄漏。

    (time-body
      (loop [i (long (dec n))
          v (f)]
    ==> (set-place mutable-place v**)
        (if (pos? i)
         (recur (unchecked-dec i) (f))
         v)))