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项目的挑战和时间表相关推荐

  1. valhalla 插件_Valhalla项目的价值

    valhalla 插件 我对Valhalla项目的进度一直很感兴趣,但是Brian Goetz最近的信息" Valhalla项目:目标 "提高了我的兴趣. 我经常喜欢Goetz的作 ...

  2. valhalla 插件_Java 15:密封类使Valhalla更加接近

    valhalla 插件 在Java 14发布之后,考虑到当前的状况,9月似乎还有很长的路要走. 在此处随时了解我们的Java 15新闻更新. JDK 15新闻 对于Java来说,这是繁忙的一周:已确认 ...

  3. server 2008 mysql 报错 0xc000007b_docker插件部署项目,volumes报错invalid volume specification...

    关于idea使用docker插件部署项目,volumes报错invalid volume specification 观察volumes那行,没写错的.但是........ 使用docker-comp ...

  4. 使用Tomcat Maven插件进行项目部署

    使用Tomcat Maven插件进行项目部署 一.使用插件原因 IDEA中使用关联本地Tomcat进行项目部署,步骤比较繁琐. 因此可以直接使用Maven中的Tomcat插件来部署项目. 二.部署步骤 ...

  5. maven-shade-plugin插件将项目打成可执行的jar包

    使用maven-shade-plugin插件将项目打成可执行的jar包 1.在pom.xml文件中添加maven-shade-plugin插件 全部文件: <build><plugi ...

  6. 使用Maven插件对项目进行打包

    问题描述: 使用Maven插件对项目进行打包时,控制台输入以下警告: [WARNING] Using platform encoding (UTF-8 actually) to copy filter ...

  7. IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证

    IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证 Docker开启远程访问 修改该Docker服务文件 加载配置与重启 验证是否开启成功 IDEA配置docker 编写 ...

  8. fileinput.js php,bootstrap fileinput 插件使用项目总结

    基础的定义及使用方法网上有很多不再概述,这儿主要写本人所使用项目时碰到的一些问题及解决方案 注:本人使用此插件主要用来上传图片之用,插件其他上传文件没有涉及 一.上传最小数量问题 通过查阅其他资料可知 ...

  9. springboot使用maven插件打包项目

    springboot使用maven插件打包项目 springboot将项目打包成jar包时,默认会将所有依赖都打包进去,这样使得打包后的jar包十分庞大.可以通过配置maven插件来打包项目,将资源文 ...

  10. 用 eclipse SVN 插件共享项目

    本文介绍了如何使用 eclipse SVN 插件来共享项目. 选择要共享的项目,右键点击"Share Project" 选择SVN 新建一个 SVN 资源地址 点击"Fi ...

最新文章

  1. Activity启动流程详解
  2. remo video repair中文版
  3. ArcGIS JS API 4.10跨域问题(本地切片无法加载)解决办法
  4. Java程序利用POJ读写Excel的.xls或.xlsx文件所需的3个jar包
  5. init(coder:)_2018年《 New Coder》调查:31,000人告诉我们他们如何学习编码并在工作中获得工作…
  6. 双表联查mysql_MySQL的双表多表联查
  7. spring冲刺第九天
  8. 高级Javascript调试——console.table()
  9. shell脚本if语句判断
  10. python经典实例pdf-Python机器学习经典实例_PDF电子书
  11. 编曲技巧:使用FL Studio来制作停顿的效果
  12. python安装pytesser模块
  13. .Net程序逆向入门教程
  14. [玩转BLE]瑞昱RTL8762CMF蓝牙5.0(烧录篇)
  15. 如何用python计算年龄_python 实现年龄计算程序
  16. 关于近段时间学习历史的点滴记录
  17. stm32中的“hello world”
  18. sinc函数卷积_从采样点到声音:sinc函数和卷积
  19. VS1005 HiRes 高清录音开发板(带显示屏)
  20. iOS - 颜色选择器

热门文章

  1. 论中国老龄商城与苹果手机的营销
  2. 免费的icon资源站
  3. openssl之带你走CA认证
  4. VMware vRealize Operations 8.5 发布(下载) - 自动驾驶式 IT 运维管理
  5. 小红书KOL品牌排行榜!小红书直播数据
  6. 长沙望城区“四早”措施再落细 打好“战疫”主动战
  7. Python提取指定颜色区域并填充闭合区间
  8. HVV行动之态势感知平台(一)
  9. ctfshow 网络迷踪-耳熟能详
  10. 维度建模优劣分析(11年文章新浪博客迁移)