Java内存压力

3

Java中是否有类似于.NET中GC.AddMemoryPressure方法的功能,可以告诉运行时关于非托管内存分配的情况?


2
关于“质量标准”的东西是什么意思? - Alexander Rühl
这是一个占位文本,用于通过stackoverflow质量标准检查器。 - michael nesterenko
@misha nesterernko 占位文本?如果它不是问题的一部分,那么它就没有必要存在。 - Michael Berry
2个回答

2

直接内存在Java中是单独管理的,可以被视为“非托管”内存。在Sun/Oracle JVM中,它有自己的内存使用限制,您可以同时达到堆大小和直接内存大小的限制。

在Sun/Oracle JVM中,您可以使用内部API显式释放直接内存块。但这是很少需要做的,以下是如何操作:

ByteBuffer bb = ByteBuffer.allocateDirect(1024*1024);

((DirectBuffer) bb).cleaner().clean();

你可以重复执行这个操作一万次而不触发垃圾回收。

顺便说一下:内存映射文件只使用少量堆内存,不计入直接内存限制。你可以映射的数量实际上是无限的。(但在一个MappedByteBuffer中限制为2GB)


2
这与GC.AddMemoryPressure没有直接关系。这意味着需要重新编写应用程序,通过Java执行所有本地内存分配。对于许多本地库来说,这是不可接受的。 - yano
@yano 希望你大部分的代码都是用Java(或其他高级语言,如C#)编写的,只有在必要时才使用最少量的本地代码。 - Peter Lawrey

2
我猜在Java中这不是必需的。'如果一个小的托管对象分配了大量的非托管内存'在Java中根本不会发生,如果您通过JNI调用本机(非托管)函数,则内存不会分配给JVM的托管内存表。
参考资料:

3
严格来说,这两个运行时系统对于内存管理有不同的假设。Java/JRE只是假设这并不是非常重要。 - Donal Fellows
2
托管对象可以容纳大量本机内存和相对较少的托管内存,因此对于垃圾收集器来说看起来很好,并且不会收集这些对象。一段时间后,本机堆栈已满并抛出OutOfMemoryException异常。这就像Deflater类的问题。我在http://www.devguli.com/blog/eng/java-deflater-and-outofmemoryerror/上发现了这个问题。建议手动调用end()方法。我认为这是一种权衡,必须避免使用垃圾收集器(当使用gc时,我们不必担心内存释放)。 - michael nesterenko
@Donal Fellows:你能给我指一些阅读材料吗?我不想挑战那个说法,只是感兴趣! - home

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接