在运行时期间在我的应用程序代码中测量Scala中的功能级内存使用情况

时间:2017-05-06 03:39:08

标签: scala memory-profiling

首先,这不是一个离线"剖析任务!

我正在开发一些SCala代码库,目前我要做的是,如果函数foo消耗太多内存(让我们说超过10G),请将其删除函数并返回默认值。

所以看起来应该是这样的:

monitor{
  foo()   <--- if foo has used over 10G memory, just cut it off
}
catch {
  case MemoryUsageError => default_value
}

请注意,目前foo与我的main功能在同一个流程中运行。

有可能这样做吗?我快速搜索这些材料,只找到一种方法来显示SCala应用程序的当前内存使用情况;它并不像我想要的那样精细。

我清楚这个吗?谁能在这里点灯?非常感谢!

=============================================== =========================

请注意,我要找的是&#34; 在线&#34;方法!它不像离线分析。我的应用程序ifself应该确定foo函数的内存使用量,如果它太高,就把它剪掉。

1 个答案:

答案 0 :(得分:0)

有可能吗?

通常,jvm不会跟踪在堆上分配的对象的创建者和创建位置。这非常昂贵,对GC无关紧要。

如何与之共存

终止

  1. 自控程序。如果要终止某些连续计算,则计算不应该是连续的。您需要的是可以验证条件的检查点。例如,每次循环或每次递归调用开始时的每次迭代开始。显然,计算可能包含几个不同的阶段,而不是简单的循环,但方法是相同的。
  2. 计算和控制的分离。例如,执行具有预定Future的{​​{1}}函数,并在需要时或使用ThreadForkJoinTask方法中断它。
  3. 测量

    1. 通常只有一个或几个类可以满足大部分内存。如果实例大小相同,则可以使用对象计数器实现内存控制。通过检查算法或使用jvisualvm可以找到“重”对象的类。在实例创建期间增加计数器减少更难。释放引用时更新计数器(计算GC无法删除的实例)或使用PhantomReference(计算VM中存在的所有实例)。但是不要使用cancel()
    2. 第二种方法是java instrumentation包。它允许测量对象大小(可能有确定某类的所有对象的消耗的方法)。您也可以尝试measuring available memory。缺陷是你测量的不是某些功能的对象,而是所有功能。
    3. 时间控制在计算开始时记下时间戳,并在每个检查点测量持续时间。