5.5. JVM 堆和非堆内存
默认情况下,Data Grid 将缓存条目存储在 JVM 堆内存中。您可以将 Data Grid 配置为使用非堆存储,这意味着您的数据在受管 JVM 内存空间之外发生原生内存。
下图显示了数据网格运行的 JVM 进程的内存空间简图:
图 5.1. JVM 内存空间

JVM 堆内存
堆分成了年轻且旧的代,可帮助保持引用的 Java 对象和其他应用程序数据在内存中。GC 进程从无法访问的对象回收空间,在ng generation 内存池中运行更频繁。
当 Data Grid 将缓存条目存储在 JVM 堆内存中时,GC 运行会在开始将数据添加到缓存时完成。因为 GC 是一个密集型过程,所以较长且更频繁的运行可能会降低应用程序的性能。
off-heap 内存
off-heap 内存是 JVM 内存管理之外的本地可用内存。JVM 内存空间 图显示包含类元数据的 元空间
内存池,以及从原生内存分配。该图还表示包含 Data Grid 缓存条目的原生内存的一部分。
非堆内存:
- 每个条目使用较少的内存。
- 通过避免 Garbage Collector (GC)运行来提高整个 JVM 性能。
然而,一个缺点是 JVM 堆转储不会显示存储在非堆内存中的条目。
5.5.1. 非堆数据存储
当您向非堆缓存添加条目时,Data Grid 会动态地分配原生内存到数据。
数据网格将每个密钥的序列化 byte[]
分为与标准 Java HashMap
类似的存储桶中。bucket 包括数据网格用来查找您存储在非堆内存中的条目的地址指针。
尽管数据网格将缓存条目存储在原生内存中,但运行时操作需要这些对象的 JVM 堆表示。例如,cache.get ()
操作将对象读取到堆内存,然后再返回。同样,状态传输操作将对象的子集存放在堆内存中。
对象相等
数据网格使用每个对象的序列化字节[] 而非对象实例确定低堆存储中的 Java 对象的相等性。
数据一致性
数据网格使用一组锁定来保护非堆地址空间。锁定数量是两倍的内核数,然后舍入到两个最接近的幂数。这样可确保即使是 ReadWriteLock
实例分布,以防止写操作阻止读操作。
5.5.2. 配置非堆内存
配置 Data Grid,将缓存条目存储在 JVM 堆空间之外的原生内存中。
流程
- 打开 Data Grid 配置进行编辑。
-
将
OFF_HEAP
设置为storage
属性或storage ()
方法的值。 - 通过配置驱除,为缓存的大小设置一个边界。
- 保存并关闭您的数据网格配置。
off-heap 存储
数据网格以字节为单位存储缓存条目。当数据容器有 100 个条目且数据网格获得创建新条目的请求时,会发生驱除:
XML
<replicated-cache> <memory storage="OFF_HEAP" max-count="500"/> </replicated-cache>
JSON
{ "replicated-cache" : { "memory" : { "storage" : "OBJECT", "max-count" : "500" } } }
YAML
replicatedCache: memory: storage: "OFF_HEAP" maxCount: "500"
ConfigurationBuilder
ConfigurationBuilder builder = new ConfigurationBuilder(); builder.memory().storage(StorageType.OFF_HEAP).maxCount(500);