valhalla 插件_Valhalla项目的挑战和时间表
valhalla 插件
通过所有有关Java 9和Project Jigsaw的讨论,我们不应忽视Java的另一重大变化。 希望在第10版或第11版中, Valhalla项目能够实现并介绍价值类型和专业化。
那么,这是什么一回事,项目进展如何,面临什么挑战? 几天前,Oracle的Java语言架构师和Valhalla的项目负责人Brian Goetz在JVM Language Summit 2015上的一次演讲中回答了这些问题。
我们来看一下。
总览
这篇文章将介绍Goetz演讲“冒险之路到Valhalla”的四个部分中的三个。
他以序言开头,我为那些尚不了解Valhalla项目的人提供了一些补充说明。 Goetz继续展示这两个原型,其中第一个原型于去年公开发布,而第二个原型仅在两周前发布。 由于这篇文章已经足够长了,因此我将不讨论他关于未来实验的最后一部分。 如果您觉得这个话题很有趣,那么一定要看整个演讲!
全文中的所有引用均来自幻灯片或逐字记录。
这里是谈话:
(顺便说一句,JVMLS团队在几个小时内就将所有讨论都在线上获得了赞誉!)
如果您可以节省50分钟,那就去看吧! 然后,无需阅读这篇文章。
序幕
Valhalla项目涉及的两个主要主题是价值类型和通用专业化 。
值类型
前者将允许用户定义具有相同属性(如不变性,相等性而不是标识)的“类似int”的类型,以及由此产生的性能优势。 它们之前是Java 8的基于值的类 。
(除非另有说明,否则当本文章的其余部分讨论基元时,将包括值类型。)
通用专业化
随着每个人都声明自己的原始类型,泛型无法在它们之上工作的事实(即,没有ArrayList <int> )引起的问题变得令人无法忍受。 从概念的角度来看,虽然必须对原语进行装箱,但它具有显着的性能成本。
首先,存储对象而不是基元会花费额外的内存(例如,用于对象标头)。 然后,更糟的是,装箱会破坏缓存的局部性 。 当CPU缓存一个整数数组时,它仅获取指向实际值的指针。 提取这些是额外的随机内存访问。 当CPU主要在等待高速缓存未命中时,这种额外级别的间接开销会付出巨大的代价,并可能破坏并行化。
因此,Valhalla项目的另一个目标是扩大参数多态性的范围,以使泛型能够覆盖基元。 为了获得成功,JVM应该使用基元而不是用于通用类中的通用字段,参数和返回值的框。
由于可能的实现方式,这称为通用专业化 。
因此,泛型需要与值类型很好地配合使用,并且原语可以伴随而来。
泛型的现状
由于擦除,类型变量被擦除到其边界,即ArrayList <Integer>有效地变为ArrayList <Object> (或者仅仅是ArrayList )。 这样的界限必须是所有可能实例化的超类型。 但是Java在基本类型和引用类型之上没有类型。
另外,JVM字节码指令通常是正交的,即沿同一行分割。 一个aload或ASTORE只能移动引用。 专业变体具有用于原语,如ILOAD或istore为int类型 。 没有字节码可以同时移动引用和int 。
因此,类型系统和字节码指令集都无法完成生成原语的任务。 十多年前开发出仿制药时,这已广为人知,作为妥协,决定只是不允许这样做。
今天的问题来自昨天的解决方案...
兼容性!
当然,Valhalla项目下发生的所有事情都必须向后兼容。 这有几种形式:
- 二进制兼容性 –现有字节码(即已编译的类文件)必须继续表示同一意思。 这样可以确保依赖项继续工作而无需重新编译。
- 源代码兼容性 –源文件必须继续具有完全相同的含义,因此重新编译它们一定不能“仅仅因为语言已更改”而更改任何内容。
- 迁移兼容性 –来自不同Java版本的编译类必须协同工作,以允许一次迁移一个依赖项。
另一个要求是不要使JVM模仿太多的Java语言。 这样做将迫使其他JVM语言处理Java语言的语义。
大约一年前,Goetz和他的同事展示了专业化的第一个实验性实现。
想法
在此原型中,编译器继续生成已擦除的类文件,但使用其他类型信息对其进行了扩充。
VM会忽略此信息,但将由专化器使用 ,这是类加载器的新组成部分。 后者将识别何时需要带有原始类型参数的类,并让专业化工具从已删除但已增强的类文件中即时生成它。
通过擦除,一个类的所有通用实例都使用相同的类文件。 相反,为每种原始类型创建一个新的类文件称为specialization 。
细节
在该原型中,使用“名称处理技术”描述了专门的类。 类名后面附加一个字符串,该字符串指示哪种类型参数专用于哪个原语。 例如, ArrayList $ { 0 = I }的意思是“用第一个类型变量int实例化的ArrayList ”。
在专业化期间,必须更改签名和字节码。 为了正确地做到这一点,专门化者需要知道哪些对象出现(所有通用类型都被擦除了)必须专门化为哪种类型。 所需的签名信息已经大部分存在于类文件中,并且原型使用附加的类型元数据注释字节码。
从Goetz的8:44起 ,我们给出了几个如何进行的示例。 他还使用它们来指出这种实现必须要注意的一些细节,例如泛型方法的主题。
我知道那是很多快速的挥手。 关键是,这很简单,但是却有很多复杂性。
摘要
该实验表明,基于类文件元数据的即时专业化无需更改虚拟机即可工作。 这些都是重要的成就,但也有不利的弊端。
首先,它需要实现一组复杂的细节。
其次,也许是最重要的是,它具有有问题的类型系统特征。 在不更改VM的情况下,仍然没有int和String的公共超类型,因此也没有ArrayList <int>和ArrayList <String>的公共超类型。 这意味着无法声明“ ArrayList的任何实例化”。
第三,这具有可怕的代码共享属性。 即使ArrayList <int>和ArrayList <String>的大部分代码是相同的,也可以在ArrayList $ { 0 = I }和ArrayList中重复。
死亡减少1000点。
第二个非常新的原型解决了有问题的类型系统特征。
问题
当前,无界通配符表示“类的任何实例”,例如ArrayList < ? >表示“任何ArrayList ”。 它们被大量使用,尤其是库开发人员。 在ArrayList <int>和ArrayList <String>是不同类的系统中,通配符可能更为重要,因为它们弥合了它们之间的鸿沟并“表达了基本的ArrayList -ness”。
但是如果我们假设ArrayList < ? >是ArrayList <int>的超类型,我们最终会遇到需要多个类继承的情况。 原因是ArrayList <T>扩展了AbstractList <T>,所以我们也希望ArrayList <int>扩展AbstractList <int> 。 现在ArrayList <int>将扩展ArrayList < ? >和AbstractList <int> (没有继承关系)。
(请注意,与当前泛型的区别在于擦除。在VM中, ArrayList <Integer>和ArrayList < ? >是同一类ArrayList ,可以自由扩展AbstractList 。)
根本原因是,当ArrayList < ? >看起来似乎意味着“任何ArrayList ”,实际上意味着ArrayList < ? 扩展 Object > ,即“引用类型上的任何ArrayList ”。
想法
原型引入了带有ref , val和any的通配符新层次结构:
- ref包含所有引用类型并替换?
- val包含所有原语和值类型(原型当前不支持该值,并且在谈话中未提及,但已在Valhalla邮件列表中宣布 )
- 任何同时包含ref和val
专用类的多重继承将通过使用合成接口表示任意类型来解决。 ArrayList <int>因此将扩展AbstractList <int>并实现ArrayList <any> 。
细节
层次结构
ArrayList <ref> ,它是ArrayList < 吗? > ,将继续为已擦除类型。
为了表示ArrayList <any> ,编译器将创建一个ArrayList $ any接口。 它将由ArrayList生成的所有类(例如ArrayList <int>和已擦除的ArrayList )实现,并将扩展与超类相对应的所有综合接口,例如AbstractList <any>的 AbstractList $ any 。
该接口将包含该类的所有方法的声明以及其字段的访问器。 因为仍然没有对象和基元的公共超类型,所以必须将其通用参数和返回类型装箱。
但是,仅当以ArrayList <any>的方式访问该类时,才需要采取这种绕行的方法,而直接访问是例如ArrayList <int>的 。 因此,装箱的性能成本仅由使用通配符的开发人员承担,而使用原始专业化的代码直接获得期望的改进性能。
它干净利落地工作。
你不应该相信我,事情变得复杂了。 但这是个好故事。 我们会继续前进。
从Goetz的26:33开始,提供一些示例来解释一些细节。
辅助功能
可访问性是VM需要更改的区域。 到目前为止,接口不能具有私有或包可见的方法。 (在Java 9中,可以使用私有默认方法,但这在这里无济于事,因为需要实现。)
一个联系在一起但更老的问题是,即使VM不允许这样做,外部类及其内部类也可以彼此访问私有成员,因为VM不允许这样做,因为它们都是不相关的类。 当前,这是通过生成桥接方法(即具有较高可见性的方法,而不是无法访问的私有成员)进行调用来解决的。
为专门的类创建更多的桥接方法将是可能的,但是很费力。 相反,可能的更改是创建类嵌套的概念。 它包含所有专用类和内部类,并且VM允许访问嵌套内部的私有成员。
这将使语言的解释与VM的解释保持一致,VM的语言将所有专业化知识和内部类作为一个单元,而VM的解释直到现在只看到一堆不相关的类。
数组
通用方法也可以采用或返回数组。 但是,虽然专业化可以将一个int装到一个Object上 ,但是int [ ] 却不是Object [ ],并且将每个单独的int装箱是一个糟糕的主意。
Arrays 2.0可能在这里有所帮助。 因为讨论需要基本熟悉该提案,所以我不会详细介绍。 总而言之,看起来他们将解决问题。
摘要
语言的更改在概念上很简单。 在没有任何变化的情况下。 类型变量可以用任何修饰,如果需要将实例分配给通配符类型,则通配符也必须使用任何通配符。
有了跨越原始类型和引用类型的通用类的通用超类型,例如ArrayList <any> ,生成的编程模型就更加合理了。 在谈到他的团队将Stream API移植到此原型的经验时,Goetz说:
真的很顺利。 这正是您想要的。 大约70%的代码刚刚消失了,因为所有手工专门化的原始东西都消失了,然后许多支持手工专门化的复杂机制也消失了,三年级的学生可以成为一个简单的图书馆写。 因此,我们认为这是一个非常成功的实验。
与现有代码的兼容性也很好。
不幸的是,第一个原型的不良代码共享属性仍然存在。 ArrayList <int>和ArrayList <String>仍然是不同的类,它们非常相似,但不共享任何代码。 下一部分(我将不在本文中介绍)解决该问题,并提出解决该问题的可能方法。
谈话非常密集,涉及很多领域。 我们已经看到,值类型的引入和期望的性能改进需要通用专业化,因此可以减少甚至防止装箱。
第一个原型通过在装入类时专门化类来实现这一目标,而无需更改JVM。 但是,存在一个问题,即类的所有实例都没有通用的超类型,因为基本类型和引用类型参数会产生完全不相关的类。 第二个原型引入了通配符ref , val和any,并使用合成接口来表示any-types。
这一切都非常令人兴奋,我等不及要尝试一下! 不幸的是,我要去度假,所以我不能一会儿了。 愚蠢的现实生活……别走了,别毁了一切!
该帖子最初发布在codefx.org上 。
翻译自: https://jaxenter.com/challenges-and-timelines-for-project-valhalla-119608.html
valhalla 插件
valhalla 插件_Valhalla项目的挑战和时间表相关推荐
- valhalla 插件_Valhalla项目的价值
valhalla 插件 我对Valhalla项目的进度一直很感兴趣,但是Brian Goetz最近的信息" Valhalla项目:目标 "提高了我的兴趣. 我经常喜欢Goetz的作 ...
- valhalla 插件_Java 15:密封类使Valhalla更加接近
valhalla 插件 在Java 14发布之后,考虑到当前的状况,9月似乎还有很长的路要走. 在此处随时了解我们的Java 15新闻更新. JDK 15新闻 对于Java来说,这是繁忙的一周:已确认 ...
- server 2008 mysql 报错 0xc000007b_docker插件部署项目,volumes报错invalid volume specification...
关于idea使用docker插件部署项目,volumes报错invalid volume specification 观察volumes那行,没写错的.但是........ 使用docker-comp ...
- 使用Tomcat Maven插件进行项目部署
使用Tomcat Maven插件进行项目部署 一.使用插件原因 IDEA中使用关联本地Tomcat进行项目部署,步骤比较繁琐. 因此可以直接使用Maven中的Tomcat插件来部署项目. 二.部署步骤 ...
- maven-shade-plugin插件将项目打成可执行的jar包
使用maven-shade-plugin插件将项目打成可执行的jar包 1.在pom.xml文件中添加maven-shade-plugin插件 全部文件: <build><plugi ...
- 使用Maven插件对项目进行打包
问题描述: 使用Maven插件对项目进行打包时,控制台输入以下警告: [WARNING] Using platform encoding (UTF-8 actually) to copy filter ...
- IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证
IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证 Docker开启远程访问 修改该Docker服务文件 加载配置与重启 验证是否开启成功 IDEA配置docker 编写 ...
- fileinput.js php,bootstrap fileinput 插件使用项目总结
基础的定义及使用方法网上有很多不再概述,这儿主要写本人所使用项目时碰到的一些问题及解决方案 注:本人使用此插件主要用来上传图片之用,插件其他上传文件没有涉及 一.上传最小数量问题 通过查阅其他资料可知 ...
- springboot使用maven插件打包项目
springboot使用maven插件打包项目 springboot将项目打包成jar包时,默认会将所有依赖都打包进去,这样使得打包后的jar包十分庞大.可以通过配置maven插件来打包项目,将资源文 ...
- 用 eclipse SVN 插件共享项目
本文介绍了如何使用 eclipse SVN 插件来共享项目. 选择要共享的项目,右键点击"Share Project" 选择SVN 新建一个 SVN 资源地址 点击"Fi ...
最新文章
- Activity启动流程详解
- remo video repair中文版
- ArcGIS JS API 4.10跨域问题(本地切片无法加载)解决办法
- Java程序利用POJ读写Excel的.xls或.xlsx文件所需的3个jar包
- init(coder:)_2018年《 New Coder》调查:31,000人告诉我们他们如何学习编码并在工作中获得工作…
- 双表联查mysql_MySQL的双表多表联查
- spring冲刺第九天
- 高级Javascript调试——console.table()
- shell脚本if语句判断
- python经典实例pdf-Python机器学习经典实例_PDF电子书
- 编曲技巧:使用FL Studio来制作停顿的效果
- python安装pytesser模块
- .Net程序逆向入门教程
- [玩转BLE]瑞昱RTL8762CMF蓝牙5.0(烧录篇)
- 如何用python计算年龄_python 实现年龄计算程序
- 关于近段时间学习历史的点滴记录
- stm32中的“hello world”
- sinc函数卷积_从采样点到声音:sinc函数和卷积
- VS1005 HiRes 高清录音开发板(带显示屏)
- iOS - 颜色选择器