[译]在 Java 和低延迟中使用 Lambdas 的主要问题

101 阅读2分钟

在 Java 和低延迟中使用 Lambdas 的主要问题是:它们会产生垃圾吗?​

我正在开发一个支持不同有线协议的库。这个想法是,你可以描述你想要 write/read 的数据,有线协议决定它是使用带有 JSon 或 YAML 字段的文本,带有 FIX 字段号的文本,带有 BSON 字段名称的二进制或 YAML 的二进制形式,带有字段名称、字段号的二进制还是根本没有字段元。值可以是固定长度、变量长度 and/or 自描述数据类型。​

这个想法是,它可以处理各种模式更改,或者如果您可以确定模式是相同的,例如通过 TCP 会话,您可以跳过所有这些,只发送数据。​

另一个大的想法是使用 lambdas 来支持这一点。​

主要问题是需要避免低延迟应用程序中的大量垃圾。从理论上讲,每次看到 lambda 代码时,这都是一个新的 Object。​

幸运的是,Java 8 显著改进了 Escape Analysis。Escape Analysis 允许 JVM 通过将新对象解压缩到堆栈上来替换它们,有效地为您提供堆栈分配。这个特性在 Java 7 中是可用的,但是它很少消除对象。注意:当您使用探查器时,它会阻止 Escape Analysis 工作,因此您不能信任使用代码注入的探查器,因为探查器可能会说一个对象正在创建,而没有探查器它不会创建一个对象。飞行记录器似乎确实扰乱了逃生分析。​

逃避分析总是有怪癖,现在看来仍然如此。例如,如果您有一个 Int Consumer 或任何其他原始消费者,可以在 Java 8 更新 20 - 更新 40 中取消 lambda 的分配。然而,异常是布尔的,这似乎没有发生。希望这将在未来的版本中得到修复。​

另一个怪癖是对象消除发生的方法的大小(内联后)很重要,在相对适度的方法中,转义分析可以放弃。​

公共空格 read Marshallable(电线)抛出 Stream Corrumted Excption{​

wire.read(Fields.I). int32(this:: i)​

. read(字段。J). int32(this:: j)​