Java Lambdas和低延迟

总览

有关在Java和低延迟中使用Lambda的主要问题是: 它们会产生垃圾吗,您能做些什么吗?

背景

我正在开发一个支持不同有线协议的库。 这样的想法是,您可以描述要写入/读取的数据,并且有线协议确定它是否使用带有JSon或YAML字段的文本,带有FIX字段号的文本,带有BSON字段名的二进制或YAML的二进制形式,具有字段名称,字段编号或完全没有字段meta的二进制。 这些值可以是固定长度,变量长度和/或自描述数据类型。

其想法是它可以处理各种模式更改,或者如果您可以确定模式是相同的(例如,通过TCP会话),则可以跳过所有内容而仅发送数据。

另一个大想法是使用lambda支持这一点。

Lambdas有什么问题

主要问题是需要在低延迟应用程序中避免大量垃圾。 名义上,每次您看到lambda代码时,这都是一个新对象。

幸运的是,Java 8大大改进了Escape Analysis 。 Escape Analysis使JVM通过将新对象解包到堆栈中来替换它们,从而有效地为您分配了堆栈。 Java 7中提供了此功能,但是很少消除对象。 注意:使用探查器时,它往往会阻止Escape Analysis正常运行,因此您不能信任使用代码注入的探查器,因为探查器可能会说正在创建对象,而没有探查器则不会创建对象。 Flight Recorder似乎确实与Escape Analysis混为一谈。

Escape Analysis一直都有古怪之处,而且看来仍然如此。 例如,如果您具有IntConsumer或任何其他原始使用者,则可以在Java 8 update 20 – update 40中消除lambda的分配。但是,在没有发生这种情况的情况下,布尔值是一个例外。 希望它将在将来的版本中修复。

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

具体情况

就我而言,我有一个读取方法,如下所示:

public void readMarshallable(Wire wire) throws StreamCorruptedException {wire.read(Fields.I).int32(this::i).read(Fields.J).int32(this::j).read(Fields.K).int32(this::k).read(Fields.L).int32(this::l).read(Fields.M).int32(this::m).read(Fields.N).int32(this::n).read(Fields.O).int32(this::o).read(Fields.P).int32(this::p).read(Fields.Q).int32(this::q).read(Fields.R).int32(this::r).read(Fields.S).int32(this::s).read(Fields.T).int32(this::t).read(Fields.U).int32(this::u).read(Fields.V).int32(this::v).read(Fields.W).int32(this::w).read(Fields.X).int32(this::x);
}

我使用lambda来设置框架可以处理可选,缺失或乱序的字段。 在最佳情况下,可以按提供的顺序使用字段。 在模式更改的情况下,顺序可以不同或具有不同的字段集。 使用lambda可使框架以不同方式处理顺序字段和乱序字段。

使用此代码,我进行了测试,对对象进行了1000万次序列化和反序列化。 我将JVM配置为具有-Xmn14m -XX:SurvivorRatio=5的eden大小为10 MB的伊甸园空间-Xmn14m -XX:SurvivorRatio=5空间是比率为5:2的两个生存空间的5倍。 Eden空间是年轻一代总数的5/7,即10 MB。

通过具有10 MB的Eden大小和1000万次测试,我可以通过计算-verbose:gc打印的GC的数量来估计产生的垃圾。对于我得到的每个GC,每个测试平均要创建一个字节。 当我改变序列化和反序列化的字段数量时,我在Intel i7-3970X上获得了以下结果。

Lambda相关垃圾

在此图表中,您可以看到,对于以相同方法反序列化的1到8个字段(即最多8个lambda),几乎不会创建垃圾,即最多只有一个GC。 但是,在9个或更多字段或Lambda上,转义分析失败,并且您将创建垃圾,垃圾随文件数的增加而线性增加。

我不希望您相信8是一个神奇的数字。 尽管我找不到这样的命令行设置,但它很可能是方法字节数的限制。 当方法增长到170字节时,会发生差异。

有什么可以做的吗? 最简单的“修复”方法是将一种方法中的一半字段反序列化,将另一种字段中的一半字段反序列化,从而将代码分为两种方法(如果需要,可以将更多方法拆分),从而能够在不产生垃圾的情况下反序列化9到16个字段。 这是“ bytes(2)”和“ ns(2)”的结果。 通过消除垃圾,代码的平均运行速度也更快。

注意:使用14 x 32位整数对对象进行序列化和反序列化的时间少于100 ns。

其他说明:

当使用事件探查器YourKit(在这种情况下)时,由于Escape Analysis失败,没有产生垃圾的代码开始产生垃圾。

我打印了方法内联 ,发现某些关键方法中的assert语句阻止了它们的内联,因为这使方法变大了。 我通过在启用断言的情况下通过工厂方法创建断言的方式来创建by main类的子类来解决此问题。 默认类没有断言,也没有性能影响。

在移动这些断言之前,我只能反序列化7个字段而不会触发垃圾回收。

当我用匿名内部类替换lambda时,我看到了类似的对象消除,尽管在大多数情况下,如果可以使用首选的lambda。

结论

Java 8似乎在清除寿命很短的对象产生的垃圾方面要聪明得多。 这意味着在低延迟应用程序中可以选择诸如传递lambda之类的技术。

编辑

尽管我不确定为什么,但我找到了在这种情况下有用的选项。

如果我使用选项-XX:InlineSmallCode=1000 (默认值)并将其更改为-XX:InlineSmallCode=5000则上面的“已修复”示例开始产生垃圾,但是如果将其减少为-XX:InlineSmallCode=500甚至是代码我最初给出的示例不产生垃圾。

翻译自: https://www.javacodegeeks.com/2015/01/java-lambdas-and-low-latency.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTP协议/RTSP协议/RTMP协议的区别

RTSP、 RTMP、HTTP的共同点、区别 共同点: 1:RTSP RTMP HTTP都是在应用应用层。 2: 理论上RTSP RTMP HTTP都可以做直播和点播,但一般做直播用RTSP RTMP,做点播用HTTP。做视频会议的时候原来用SIP协议,现…

2013搜狗校园招聘笔试题

研习了Linux公社发布的2013搜狗校园招聘笔试题,还是有些收获的。 //第一题:以下程序的输出是___________________ class Base { public:Base(int j):i(j){}virtual ~Base(){}void func1(){i * 10; func2();}int getValue(){return i;} protected:virtual…

Java中的线程本地存储

开发人员中鲜为人知的功能之一是线程本地存储。 这个想法很简单,并且在需要数据的情况下很有用。 如果我们有两个线程,则它们引用相同的全局变量,但我们希望它们具有彼此独立初始化的单独值。 大多数主要的编程语言都有该概念的实现。 例如&…

jsp中@import导入外部样式表与link链入外部样式表的区别

昨天碰到同事问了一个问题,impor导入外部样式与link链入外部样式的优先级是怎样的,为什么实验的结果是按照样式表导入后的位置来决定优先级。今天就这个问题具体总结如下: 先解释一下网页添加css样式的方法,一共有四种&#xff0c…

EBS调试

一、在请求中的调试: 1、用系统函数fnd_file.PUT_LINE(),然后在请求的查看日志中就可以看到 例如: fnd_file.PUT_LINE(fnd_file.log, l_customer_type); 其中l_customer_type就是要查看的变量。 2、先建一张表,然后在程序中执行…

Acision推出“ forgeathon” –第一个WebRTC应用挑战

Acision推出了“ forgeathon”,这是 面向全球开发人员的 首个在线丰富网络通信(WebRTC)应用挑战 加入Forgeathon,让Acision帮助您将应用程序或服务推向全球! 英国雷丁– 2015年1月6 日 :安全,…

SQL Server 中的ROWID

在SQL Server中没有像Orcal中的rowid,但是可以运用一定的变通达到这个效果。1、建立临时表,其中包含rowid,2、重命名原表后删除临时表USE TianzxSELECT identity(int,1,1) as rowid,flow.* into temptable from flow--建立临时表,…

jsp中四种传递参数的方法

jsp中四种传递参数的方法如下&#xff1a; 1、form表单 2、request.setAttribute();和request.getAttribute(); 3、超链接&#xff1a;<a herf"index.jsp"?aa&bb&cc>name</a> 4、<jsp:param> 下面一一举例说明&#xff1a; 1、form表…

多个退货单

我曾经听说过&#xff0c;过去人们为使方法具有单个出口点而奋斗。 我知道这是一种过时的方法&#xff0c;从未认为它特别值得注意。 但是最近&#xff0c;我与一些仍坚持该想法的开发人员进行了联系&#xff08;最后一次是在这里 &#xff09;&#xff0c;这让我开始思考。 因…

GO 语言编程 windows 环境搭建

参考 : http://blog.csdn.net/love_se/article/details/7754274 首先是安装Go&#xff0c;这里有很详细的安装说明&#xff0c;http://code.google.com/p/golang-china/wiki/Install 或者http://golang.org/doc/install 下面我们在window下面安装&#xff0c;google有提供win安…

建立代理,而不是框架

自从引入Java注释以来&#xff0c;它已成为大型应用程序框架API的组成部分。 此类API的良好示例是Spring或Hibernate的示例&#xff0c;其中添加了几行注释代码可实现非常复杂的程序逻辑。 尽管人们可以争论这些特定API的缺点&#xff0c;但大多数开发人员都会同意&#xff0c;…

HttpServletRequest.getContextPath()取得的路径

如果项目名称为test,你在浏览器中输入请求路径&#xff1a;http://localhost:8080/test/pc/list.jsp 执行下面向行代码后打印出如下结果&#xff1a; 1、 System.out.println(request.getContextPath()); 打印结果&#xff1a;/test 2、System.out.println(request.getSer…

合理的嵌入式开发学习路线

最近网上好多新手问我&#xff0c;怎么样学习嵌入式开发&#xff1f;其实这个问题很复杂&#xff0c;因为嵌入式开发是个非常复杂的领域&#xff0c;既有深度&#xff0c;也有广度&#xff0c;是个软硬结合的领域。。。我研究的时间也不长&#xff0c;不过以后可能会研究RTOS这…

重点保护

在“ Java的一些句子 ”一文中&#xff0c;我写道&#xff1a; “受保护的方法和字段可以在同一包中的类中使用&#xff08;到目前为止与私有包相同&#xff09;&#xff0c;此外&#xff0c;还可以从其他类中使用受保护的方法和字段&#xff0c;这些类扩展了包含受保护的字段或…

机打发票打印管理

最近公司也从手写发票换成了机打发票&#xff0c;便应财务的要求做了这么一个简单的发票管理及打印系统&#xff0c;程序并不复杂。 使用C#&#xff08;2.0&#xff09; Access&#xff08;97-2003版&#xff09;/WinForm形式 系统菜单中有企业基本信息设置&#xff0c;见图4…

程序员需要了解的一点组织行为学知识

程序员由于天天和逻辑打交道&#xff0c;所以在世故的人眼里往往显得过于简单。 近来看组织行为学&#xff0c;发现其中一节列了很多特别的技能。 考虑到也许他们对程序员群体很有启示意义&#xff0c;就追加了一点说明&#xff0c;把它放在博客里。 相信这对想成为管理者的程序…

序列化的概念

讨论了为什么Optional不可序列化以及如何处理&#xff08;即将推出&#xff09;之后&#xff0c;让我们仔细看看序列化。 总览 这篇文章介绍了序列化的一些关键概念。 它尝试精简地执行此操作&#xff0c;而不会涉及太多细节&#xff0c;包括将建议降至最低。 它没有叙述&…

正则表达式总结及一些有用的例子

背景 正则表达式的用处十分广泛&#xff1a;字符串处理、输入验证等&#xff0c;特别是在爬取网页中对网页内容的清洗更需要正则。 正则表达式 基本所有的语言都支持正则表达式&#xff0c;或者内置或者引入。正则的语法很多&#xff0c;但每种语言对正则支持的程度都不同&…

对PostgreSQL SPI例子的学习

[作者&#xff1a;技术者高健博客园 mail: luckyjackgaogmail.com ] http://www.postgresql.org/docs/9.1/static/spi-examples.html SPI 的例子里面没有说&#xff0c;是如何编译和部署的&#xff0c;我这里补充下&#xff1a; 编译与部署&#xff1a; [rootlocalhost soft]#…

Java飞行记录器(JFR)

JFR是Java分析器&#xff0c;它使您可以研究代码的运行时特征。 通常&#xff0c;您将使用探查器来确定代码的哪些部分导致大量内存分配或导致消耗过多的CPU。 有很多产品在那里。 过去&#xff0c;我使用过YourKit&#xff0c;OptimizeIt&#xff0c;JProfiler&#xff0c;Ne…