我的上一篇文章是在几周前写的,在收到一些有效的反馈后,我想澄清几点,作为本文的序言。

“ 使用零垃圾创建数百万个对象 ”的主要收获应该是,使用Chronicle,在编写Java程序时,您不会“局限于”使用jvm分配的堆内存。 也许这篇文章更恰当地标题为“使用零堆创建数百万个对象”。 我想指出的另一点是,当您没有堆内存时,不会引起GC活动。

我使用术语“垃圾”来描述分配在堆上的对象的事实使人感到困惑。 尽管分配的对象引起GC活动,但实际上它们不是垃圾。

我设计了一个示例来说明一个,一个是ChronicleMap不使用堆内存,而ConcurrentHashMap则使用第二个;当您使用堆内存时,您不能忽略GC。 至少您需要仔细调整系统,以确保您不会因为长时间的GC暂停而遭受痛苦。 这并不意味着从堆外分配没有任何问题(请参阅本文的结尾),也并不意味着您无法通过堆上解决方案进行优化以消除GC。 摆脱困境绝不是解决所有Java性能问题的灵丹妙药,但是对于非常具体的解决方案,它可以提供有趣的机会,我将在本文中讨论其中的一些机会。

有时可能需要在JVM之间共享数据。

现在让我们简化一下,假设您有两个JVM在同一台计算机上运行,​​其中一个或两个都希望看到彼此的更新。 每个Java程序都有一个ConcurrentHashMap ,它将对其进行更新,这些更新将被存储并在以后可供使用。 但是,程序如何将另一个Java程序应用的更新获取到其映射?

从根本上讲,不能在JVM之间直接共享HashMapConcurrentHashMap类的JDK堆集合。 这是因为堆内存由分配它的JVM包含。 因此,当JVM退出时,内存被释放并且数据不再可用,因此没有在JVM的生命周期之外持久保留内存的隐式方法。 因此,您需要找到其他机制来在JVM之间共享数据。 通常,您可以将数据库用作外部共享存储和消息传递服务,以将数据更新发送给其他进程,以通知他们某些数据已被更新。

这导致以下体系结构:

这种体系结构的问题是,使用会丢失HashMap的内存速度,特别是如果写入数据库的速度不是那么快,并且您希望在通过消息传递服务发送消息之前坚持写操作。 同样,许多解决方案都将涉及TCP调用,这可能再次成为延迟的源头。

当然,与使用诸如将日志记录到磁盘的机制(例如,使用ChronicleQueue之类的产品)写入成熟的数据库相比,存在持久化数据的方法要快得多。 但是,如果您确实使用日志,则仍然必须建立所有逻辑以在重新启动时重新创建Map数据结构,更不用说必须在另一个JVM上保持Map类型结构的最新状态。

(您可能根本想保留数据的原因是,这样您应该能够在重新启动时进行恢复,而不必从源中重播所有数据)。 除了此体系结构引入的延迟之外,还必须处理数据库和消息传递服务的额外代码和配置。

即使接受这种功能都可以封装在框架中,如果您的内存Map实际上在JVM外部可见,那不是很好。 Map应该能够隐式持久化数据,以便其数据独立于JVM的生存时间可用。 它应该允许使用与使用堆上映射相同的“内存”速度进行访问。

这就是ChronicleMap用处ChronicleMapjava.util.ConcurrentMap的实现,但重要的是,它使用了堆外内存 ,该内存在JVM外部对于计算机上运行的任何其他进程都是可见的。 (有关堆上内存与堆外内存的讨论,请参见此处 )。

每个JVM将创建一个指向相同的内存映射文件的ChronicleMap 。 当一个进程写入其ChronicleMap ,另一个进程可以立即(约40纳秒)在其ChronicleMap查看更新。 由于数据存储在JVM外部的内存中,因此JVM退出不会导致任何数据丢失。 数据将保存在内存中(假设不需要分页),并且在JVM重新启动时,它可以非常快速地将其重新映射。 丢失数据的唯一方法是,如果操作系统崩溃而脏页尚未保存到磁盘上,则该操作系统崩溃。 解决方案是Chronicle 支持的使用复制,但超出了本文的范围。

其架构就是这样的:

有关ChronicleMap入门的代码示例,请参阅我的上一篇文章或此处的官方ChronicleMap教程。

在进入ChronicleMap之前,需要考虑很多注意事项和权衡取舍。

  • ChronicleMap条目必须可序列化。 对于对性能非常敏感的系统,您需要实现Chronicle提供的称为BytesMarshallable的自定义序列化。 尽管这很容易实现,但堆映射并不是必需的。 (话虽如此,将数据存储到数据库中当然也需要某种序列化方法。)
  • 即使使用BytesMarshallable序列化,任何序列化的开销对于某些系统而言也可能很重要。 在这种情况下,可以采用Chronicle支持的零拷贝技术(有关更多详细信息,请参阅我的上一篇博客文章 ),以最大程度地降低序列化的成本。 但是,与使用“普通” Java相比,实现起来有些棘手。 另一方面,在对延迟敏感的程序中,它将具有不创建任何对象的巨大好处,这些对象随后可能需要由GC清理。
  • ChronicleMap不会调整大小,因此必须预先调整大小。 如果您不知道预期有多少个项目,可能会出现问题。 但是,应该指出的是,至少在Linux上,过度设置不是一个大问题,因为Linux被动分配内存。
  • 编年史依靠操作系统异步刷新到磁盘。 如果要绝对确定数据已实际写入磁盘(而不是仅保存在内存中),则需要复制到另一台计算机。 实际上,任何关键任务系统都应复制到另一台机器上,因此在采用《纪事报》时这可能不是大问题。
  • ChronicleMap将受到操作系统内存分页问题的影响。 如果内存已调出并且必须换回,则延迟会引入系统。 因此,即使您能够创建大小远远超过主内存的ChronicleMaps,您也必须意识到根据数据访问模式的不同,可能会发生分页。

翻译自: https://www.javacodegeeks.com/2015/04/chroniclemap-java-architecture-with-off-heap-memory.html

ChronicleMap –具有堆外内存的Java体系结构相关推荐

  1. jvm 堆外内存_jvm┃java内存区域,跳槽大厂必会知识点

    正文约: 2000字 预计阅读时间: 6分钟 文章首发于我的微信公众号:哪儿来的moon,欢迎大家关注 目录 目录 前言 正文 1.程序计数器 2.虚拟机栈 3.本地方法栈 4.堆 5.方法区 6.直 ...

  2. java堆外内存泄漏分析排查

    JAVA堆外内存分析 文章目录 JAVA堆外内存分析 1.前言 2.准备 3.具体分析 3.1堆外溢出风险判断 3.1.1确认java进程号 3.1.2查看此java进程的jvm参数 3.1.3查看j ...

  3. java堆内存和堆外内存_Java堆空间,本机堆和内存问题

    java堆内存和堆外内存 最近,我正在和一个朋友讨论为什么Java进程使用的内存比启动Java进程时设置的最大堆多. 代码创建的所有Java对象都是在Java堆空间内创建的,其大小由-Xmx选项定义. ...

  4. Java堆外内存的使用

    堆外内存的回收见HeapByteBuffer和DirectByteBuffer以及回收DirectByteBuffer 基本类型长度 在Java中有很多的基本类型,比如: byte,一个字节是8位bi ...

  5. java堆外内存6_Java堆外内存排查小结

    简介 JVM堆外内存难排查但经常会出现问题,这可能是目前最全的JVM堆外内存排查思路.之前的文章排版太乱,现在整理重发一下,内容是一样的. 通过本文,你应该了解: pmap 命令 gdb 命令 per ...

  6. java nio 堆外内存_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  7. Java堆外内存:堆外内存溢出问题排查

    一.堆外内存组成 通常JVM的参数我们会配置 -Xms 堆初始内存  -Xmx 堆最大内存  -XX:+UseG1GC/CMS 垃圾回收器  -XX:+DisableExplicitGC 禁止显示GC ...

  8. java 监控 native 内存_JVM NativeMemoryTracking 分析堆外内存泄露

    Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能.我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据. NMT介绍 工欲 ...

  9. Cassandra Java堆外内存排查经历全记录

    背景 最近准备上线cassandra这个产品,同事在做一些小规格ECS(8G)的压测.压测时候比较容易触发OOM Killer,把cassandra进程干掉.问题是8G这个规格我配置的heap(Xmx ...

最新文章

  1. LabVIEW实现PCB电路板坐标定位(实战篇—2)
  2. 如何从零起步搭建一个分布式对象存储的架构
  3. 新闻与传播c刊_新闻传播类c刊有哪些
  4. 第二十三章:准备原材料
  5. 从第一范式到第二范式所做的操作是_数据库设计三大范式
  6. JavaScript学习(七十八)—实现对数据的浅拷贝和深拷贝
  7. 多线程的实现方式01 Thread
  8. 帝国的黄昏:SQL是世界上最牛逼的语言
  9. Umeng社会化组件使用笔记
  10. unity游戏框架学习-资源管理
  11. 邱锡鹏神经网络怎么样,邱锡鹏 神经网络pdf
  12. 【大模型迁移 2022】Exploring Visual Prompts for Adapting Large-Scale Models
  13. 读书笔记:《Being Mortal》
  14. 三国志战略版:魏国新黑科技,程昱春华满宠
  15. iPad 生产力指南:如何把MathType7安装在iPad中,方便写公式,写论文,公式编辑器,完全免费
  16. Linux如何打开U盘
  17. 工业相机基础知识详述 —— 焦平面,像平面,弥散圆,光圈,分辨率,景深,接口,靶面尺寸
  18. 我的2017——作为一名程序员,我重新思考了我生活的目标
  19. 【分布式】分布式环境下如何保证数据库和缓存的双写一致性?看完我明白了!!
  20. cl 编译器环境配置问题

热门文章

  1. React中的各个目录文件功能
  2. spark submit参数及调优
  3. linux跑循环脚本占内存,Linux下实现脚本监测特定进程占用内存情况
  4. unity 3d shaderlab 开发实战详解_vue实战开发011:使用router-view嵌套路由详解
  5. MySQL8.0: Serialized Dictionary Information(SDI) 浅析
  6. 算法设计与分析:(二)动态规划
  7. javafx 图标_JavaFX技巧32:需要图标吗? 使用Ikonli!
  8. java实现可选形参_Java:可选的可选实现
  9. jax-rs jax-ws_什么是JAX-RS注释? (第3部分)
  10. junit5和junit4_JUnit 5 –下一代JUnit的初步了解