我正在构建一个Scala封装器,围绕Torch库。我正在使用Swig构建粘合层。它允许我创建堆外张量,只有通过显式调用库的静态方法才能释放。然而,我想以命令式的方式使用张量,而不必担心释放内存,就像Java中的任何普通对象一样。
我所能想到的唯一方法是以下方式(误用)JVM的垃圾收集器:
“内存管理器”跟踪消耗的堆外内存量,当达到阈值时,调用
张量本身包含在一个类中,该类有一个finalize方法,用于释放离堆内存,如下所示:
我知道这是一种天真的方法,但我能用它逃避吗?它似乎很好用,即使在并行运行时(这会生成大量不必要的
谢谢。
我所能想到的唯一方法是以下方式(误用)JVM的垃圾收集器:
“内存管理器”跟踪消耗的堆外内存量,当达到阈值时,调用
System.gc()
。object MemoryManager {
val Threshold: Long = 2L * 1024L * 1024L * 1024L // 2 GB
val FloatSize = 4
private val hiMemMark = new AtomicLong(0)
def dec(size: Long): Long = hiMemMark.addAndGet(-size * FloatSize)
def inc(size: Long): Long = hiMemMark.addAndGet(size * FloatSize)
def memCheck(size: Long): Unit = {
val level = inc(size)
if (level > Threshold) {
System.gc()
}
}
}
张量本身包含在一个类中,该类有一个finalize方法,用于释放离堆内存,如下所示:
class Tensor private (val payload: SWIGTYPE_p_THFloatTensor) {
def numel: Int = TH.THFloatTensor_numel(payload)
override def finalize(): Unit = {
val memSize = MemoryManager.dec(numel)
TH.THFloatTensor_free(payload)
}
}
张量的创建是通过工厂方法完成的,该方法会通知内存管理器。例如,要创建一个全为零的张量:
object Tensor {
def zeros(shape: List[Int]): Tensor = {
MemoryManager.memCheck(shape.product)
val storage = ... // boilerplate
val t = TH.THFloatTensor_new
TH.THFloatTensor_zeros(t, storage)
new Tensor(t)
}
}
我知道这是一种天真的方法,但我能用它逃避吗?它似乎很好用,即使在并行运行时(这会生成大量不必要的
System.gc()
调用,但除此之外没有其他问题)。或者您能想到更好的解决方案吗?谢谢。