Peter Lawrey 谈 JDK9 中的 VarHandle & 使 Java 中的数据

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

Peter Lawrey 一直致力于突破 Java 性能的界限,因此您真的没有理由不关注他的 博客 。这个月我借此机会采访了 Peter,了解他目前从事的 Chronicle-Engine 项目的提交数量。

首先,请简单介绍一下您的背景和目前的工作。

我是一名 Java Champion,在高性能 Java 应用程序(例如交易、风险和数据分发系统)方面拥有 20 年的经验。在我的日常工作中,我是 Chronicle Software 的首席执行官,该公司专门开发软件,让每个 Java 开发人员都能访问真正快速的数据。我还是 Performance Java User's Group(1600 名成员)的创始人,我的博客 VanillaJava 的点击率已超过 300 万。

你和你的同事现在正朝着什么目标冲刺?

我们已经发布了 Chronicle-Engine 的稳定版本,我们正在寻求完善测试。在过去的几年里,我们一直在开发软件,通过我们的旗舰产品 Chronicle-Queue 和 Chronicle-Map 使 Java 中的数据变得超快。 Chronicle-Engine 是 Chronicle-Queue 和 Chronicle-Map 之上的一层,用于支持数据虚拟化。 Chronicle-Engine 的目标就是简化。开发人员可以使用标准的 ConcurrentMap 或 Pub/Sub API,实际的实现被抽象出来并可以被替换。例如,它可以是纯内存、平面文件、Chronicle Map、JDBC、LDAP 或自定义后端存储。这允许开发人员为响应式环境编写简单的代码,而不必为每个可能的后端存储学习新的 API。我们的实时查询 API 基于 Streams API,您的 lambda 在服务器上执行以提高性能。

为了让所有平台都能访问数据,我们希望支持 Chronicle Engine 作为 NFS 服务器。这意味着任何 NFS 客户端都可以使用任何语言访问该引擎。


 # map.put("Hello", "World")
 $ echo World > Hello

 # System.out.println(map.get("MOTD"));

 $ cat MOTD


注意:文件名是底层store的key,文件内容是value。

你在各种会议上进行了几次成功的演讲。在过去的两年中,您在巡回会议上讨论的主题是什么?

我一直在谈论 Java 8 中的 lambda 以及它们有多酷,特别是 Java 8 JVM 如何将对象放在堆栈上以自动消除垃圾。我们使用分布式 lambda 来简化编写客户端代码以在服务器上执行的过程。即在客户端你使用 lambda,但它被发送到服务器以执行、性能和原子性。例如


 # map.put("Hello", "World")
 $ echo World > Hello

 # System.out.println(map.get("MOTD"));

 $ cat MOTD


我也一直在谈论通过使用本机内存在 Java 中存储非常大的数据集。例如,一个客户端持有 70 GB 的 Java 数据,具有名义堆使用率。进程重启后,使所有数据可用仅增加 10 毫秒。我们有两个客户以每秒超过 1000 万个事件的峰值速率持久保存数据而没有消息丢失。

您在演讲和社区中经常收到哪些问题?

最常见的问题是公司有多大,我们的办公室在哪里。我们有 4 名全职开发人员和 4 名兼职员工。我们要么在家工作,要么在现场工作。

在与您所做的工作相关的 Java 9 中,有什么是您真正关注的吗?

对我来说最重要的是 VarHandle。考虑到我们经常使用它,它如何用于线程安全的堆外内存?我们仍然可以在 Java 9 中使用 Unsafe,但更愿意使用标准 API 来工作。更好的是用户定义的内部函数,可能在 Java 10 中。那真的很酷。

说到 Java 9,您如何看待将 sun.misc.Unsafe 的功能转移到 Java 9 中的 Java 公共 API 的计划,该计划在过去几周得到了广泛关注?

我所看到的问题是,他们计划在没有替代品的情况下删除某些东西——或者至少是我们可以确信的替代品(它甚至还没有出现在 Java 9 的 EA 版本中)。

他们拿走了 tools.jar 但编译器 API 从 Java 6 开始就存在了,所以这应该不是什么大问题。

另一个问题是,设计人员对于为什么首先使用 Unsafe 并没有表现出太多的理解。他们知道它已被使用,但觉得它不应该被使用,他们是唯一应该需要它的人。我们本可以使用 JNI,但这样做真的更安全吗?

在过去的几个月里,您有什么有趣或有用的技术想谈谈吗?

我认为两个项目随着时间的推移变得更加令人印象深刻。这些是 JITWatch,它允许您查看进程是如何编译的,一直到一行 Java 的机器代码。另一个是 JMH,它使编写微基准测试变得更加容易。它们已经存在了一段时间,但最近的更新意味着您应该再看看它们。

或者您现在认为有趣但尚未谈论的任何其他话题?

我认为有必要重复一下内联和转义分析的重要性。结合起来,这些可以将一个短暂存在的对象移动到堆栈中,甚至完全消除它。这对于使用 Lambda 的 Stream API 的性能至关重要,但它适用于所有 Java 对象。您过去可能避免的短期对象可能无关紧要(至少在 JVM 预热后)从低延迟的角度来看,这很重要,因为这意味着您可以再次使用对象,前提是 JVM 可以为您消除它们。