有several computer programming languages使用JVM字节码作为解释器/编译器的目标语言。在我看来,许多新的编程语言(不到15年)都在JVM上运行,我想知道是否禁止显式内存释放:
是否可以通过任何指令在字节码中显式分配 - 释放内存?相反,垃圾收集器总是可以解释内存吗?
答案 0 :(得分:6)
JVM抽象出所有内存管理。内存释放没有字节码,就像没有用于内存分配或直接内存访问的字节码一样。如果你想这样做,你必须直接或间接使用本机代码。
答案 1 :(得分:2)
JVM的一个绝对原则是,对象绝对可以保证至少与对它们的任何引用一样长。如果组中的对象保持对彼此的强引用,但组中对它们的唯一引用被封装在WeakReference
对象中,则组中的所有对象以及对它们的所有引用将不再存在,同时(WeakReference
对象可能继续存在,但他们不再拥有对任何东西的引用。)
这样做的结果是,除非或直到JVM确定不存在对它的引用,否则不能重用对象的内存。因为确保一个特定对象不存在引用所需要的时间差不多,因为它需要对所有年龄相同或更新的对象执行垃圾收集,所以尝试并没有什么好处尽快回收记忆。如果考虑GC在需要内存时运行,则尤其如此。在需要记忆之前,没有任何好处可以释放它。
答案 2 :(得分:0)
两年后,当我发现Apache Spark中的project Tungsten正在使用一种hack来使用JVM在堆中分配和取消分配内存时,我回到了这个问题。
这不是新的,所以有可能做到。您可以找到更多详细信息here 从那里我得到以下例子:
public DirectIntArray(long size) {
startIndex = unsafe.allocateMemory(size * INT_SIZE_IN_BYTES);
unsafe.setMemory(startIndex, size * INT_SIZE_IN_BYTES, (byte) 0);
}
}
public void setValue(long index, int value) {
unsafe.putInt(index(index), value);
}
public int getValue(long index) {
return unsafe.getInt(index(index));
}
private long index(long offset) {
return startIndex + offset * INT_SIZE_IN_BYTES;
}
public void destroy() {
unsafe.freeMemory(startIndex);
}
GC完全没有意识到这种方式分配的内存。我把它称为hack,因为它使用代码反射来打开内部方法,这些方法只应由ClassLoader
用来为实例创建分配内存。