1

在 OpenHFT 的Github 存储库上的 ChronicleMap在他们的文档中声明:

  Chronicle Map implements the java.util.concurrent.ConcurrentMap, that stores 
  its data off the java heap. 

我已经构建了一个编译器,并为一些分支语言的编译器实现做出了贡献。我使用过的分配堆栈上的所有内容(这就是代码生成期间可用的内容)。我从未在 JVM 和 java 编译器上工作过,但我知道通常只有堆和堆栈可用于分配类实例、局部变量、函数参数等。

有人可以解释一下我们是如何编写代码的,我们可以告诉编译器实例化诸如 ChronicalMap 之类的数据结构,让它们可用于 JVM 的垃圾收集(并通过 JVM 的一般内存管理进行跟踪功能),但生活在堆外?

我已经阅读了简单的构造文档和相关示例。我看到了,how但是与 JVM 结合到底发生了什么的原因尚不清楚。

4

2 回答 2

3

要记住的重要一点是,javac编译器并没有在优化方面做太多事情,也没有给你任何方法来指定数据存储在哪里或如何优化代码。(Java 8 中有一些不为人知的例外,例如 @Contended)

Java 的大部分可扩展性来自通常在运行时运行的库。(通常还有一个构建时间选项)要实现的关键是 Java 程序可以在运行时生成和更改代码,因此实际上大部分智能都发生在运行时。

在堆外使用的情况下,您需要一个支持此功能的库,这将直接或间接使用sun.misc.Unsafe(在大多数流行的 JVM 上)此类允许您执行该语言不支持的许多事情,但仍然是如果您是低级库构建器,则很有用。

虽然堆外内存不直接由 GC 管理,但您可以拥有代理对象,例如ByteBuffer,代理对象有一个Cleaner,这样当这些对象被 GC-ed 时,与之关联的堆外内存也会被清理。

免责声明,我写了大部分的 ChronicleMap。

于 2014-10-01T18:08:23.337 回答
1

堆外一词是指在 java 中使用“原始”内存缓冲区的能力。这些可能是来自进程地址空间的常规内存缓冲区,或者内存映射文件。

这些缓冲区是“原始的”——你自己管理它们的内容——它们不是由垃圾收集器管理的。

于 2014-10-01T18:10:17.437 回答