深入理解JVM - 动态类型语言

简介: 深入理解JVM - 动态类型语言

前言


上一节讲述了栈桢和分派的细节,这一节我们来讲讲自java语言诞生新增加的新语言特性:动态类型语言支持,这一节将会根据动态语言的特性以及相关的介绍同时讲述jvm一个重要的指令:invoke dynamic指令。但是需要注意的是:invokedy namic指令面向 的主要服务对象并非Java语言,而是其他Java虚拟机之上的其他动态类型语言


概述


  1. 介绍什么是动态类型语言,以及java为什么是静态语言的讲解。
  2. 介绍invokeDynamic指令在实际案例中的运用
  3. 介绍java实现动态语言调用的一些曲线救国的手段。


动态类型语言



什么是动态类型语言


动态类型语言的关键特征是它的类型检查的主体过程是在运行期而不是编译期。而java就是典型的静态类型语言,需要在编码的过程中确定的,静态的语言也意味着所有的类型在编译器必须确定。


为什么java是静态类型?


这里牵扯到一个问题就是为什么java是静态类型呢?我们可以看一下invokeVitual命令,这个命令根据如下的内容,确定一个属性的全类名,以及类型,在符号引用的阶段可以看到基本的内容:


invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

这些符号引用在翻译为直接引用是需要确切的类型的,所以在早期的java天生缺乏动态语言的支持。


动态语言类型支持


java在jdk7之后加入了动态语言支持,关于加入动态语言类型的支持核心是使用invoke dynamic命令, 这种方式使用了类似曲线救国的方式,也是为兼容考虑不得不做的一种妥协,比如最常见的类型数组,在java中我们必须声明确数组存放的类型,而jdk引入了invokeDynamic这个指令之后,就可以完成对于一个方法参数的动态调用。

动态类型语言是可以让对象的类型可以在运行时候再确定,比如JS和Python的var。


invokedynamic指令


下面来说下invoke这个指令是如何实现动态类型语言的,在java中是无法把一个函数作为参数传递的,更多的方式使用类似实现接口的方式进行处理,而新的指令在某种程度上是使用类似MethodHandle的方式进行处理的,MethodHandle是对通过字节码的方法指令调用的模拟,但和反射不同的是反射是基于Java语言服务的,而MethodHandler则是服务于所有虚拟机上的一种语言。

每一处含有invokedynamic指令的位置都被称作“动态调用点(Dynamically-Computed Call Site)”, 这条指令的第一个参数不再是代表方法符号引用的CONSTANT_Methodref_info常量,而是变为JDK 7 时新加入的CONSTANT_InvokeDynamic_info常量,从这个新常量中可以得到3项信息:引导方法 (Bootstrap Method,该方法存放在新增的BootstrapMethods属性中)、方法类型(MethodType)和 名称

为了更好的理解这个命令,下面我们来看下实际运行过程当中的应用,比如在jdk8中引入的lambada表达式和默认方法就是通过invokedynamic命令实现的,但是使用jdk8的实现看起来比较难以理解,下面来看一下书中给的一段案例代码:


Constant pool:
#121 = NameAndType #33:#30 // testMethod:(Ljava/lang/String;)V #123 = InvokeDynamic #0:#121 // #0:testMethod:(Ljava/lang/String;)V
public static void main(java.lang.String[]) throws java.lang.Throwable; Code:
stack=2, locals=1, args_size=1
0: ldc #23 // String abc
2: invokedynamic #123, 0 // InvokeDynamic #0:testMethod: (Ljava/lang/String;)V 7: nop
8: return
public static java.lang.invoke.CallSite BootstrapMethod(java.lang.invoke.Method Handles$Lookup, java.lang.Strin Code:
    stack=6, locals=3, args_size=3
0: new
3: dup
4: aload_0
5: ldc
7: aload_1
8: aload_2
9: invokevirtual #65
12: invokespecial #71 15: areturn
#63
#1
// class java/lang/invoke/ConstantCallSite
// class org/fenixsoft/InvokeDynamicTest
// Method java/lang/invoke/MethodHandles$ Lookup.findStatic:(Ljava/lang/Cl // Method java/lang/invoke/ConstantCallSite. "<init>":(Ljava/lang/invoke/M
复制代码


从上面的方法调用可以看到,使用的是invokeDynamic的调用指令以及参数为第123项的常量,比如如下的内容:


2: invokedynamic #123, 0 // InvokeDynamic #0:testMethod:(Ljava/lang/String;)V

而BootstrapMethod()方法中指令将会产生testMethod()方法,当然这个方法在java源码中是看不见的,而是由invokeDynamic动态生成的一个方法,当指令完成对应的方法调用之后,这个指令的调用过程也宣告结束了。


总结


本文的内容比较啊间断,主要针对动态类型语言做了一个补充,内容比较剪短,至此,jvm的内容大致以及全部讲述完毕,而关于书中的最后一节并发编程的描述,个人将会放到《并发编程实战》中进行总结(又得回去看一遍)。


写在最后


invokeDynamic主要服务的是其他语言的接入,但是从实际效果来看不是十分的理想。

相关文章
|
消息中间件 存储 缓存
Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
【2月更文挑战第20天】Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
637 2
|
负载均衡 网络协议 算法
slb监听协议与端口
SLB是云服务商提供的负载均衡服务,用于分发客户端请求到多台后端服务器,提升服务可用性和响应速度。关键概念包括监听协议(TCP、UDP、HTTP、HTTPS、TCPSSL)和监听端口。监听协议决定了SLB处理请求的方式,而监听端口则是SLB接收请求的入口。配置时需根据应用选择合适协议和端口,并可设置负载均衡算法(如轮询、最少连接等)。客户端应通过SLB统一入口访问后端服务,避免绕过SLB导致的问题。
1633 2
|
3月前
|
SQL 前端开发 API
如何物业管理(园区式)系统的行政综合板块?(附架构图+流程图+代码参考)
本文详细解析了物业管理系统的架构设计与核心模块实现,重点讲解了行政综合模块的功能、流程、数据库设计及前后端开发示例,涵盖活动公告、运营周报、人事管理、资产入库、出库耗材及雨季数据等场景。同时介绍了共用技术点与运维注意事项,帮助团队高效构建稳定、可扩展的物业管理系统,提升物业运营效率与数据管理水平。
|
5月前
|
存储 分布式计算 安全
阿里云服务器ECS实例选型参考:场景适配、应用推荐
选择阿里云服务器ECS实例之前,需要结合性能、价格、工作负载等因素,做出性价比与稳定性最优的决策。对于很多新手用户来说,在初次购买阿里云服务器的时候,面对众多实例规格往往不知道如何选择,因为云服务器实例规格不同,价格也不一样,性能表现更是千差万别。因此,在购买阿里云服务器ECS实例之前,需要结合性能、价格、工作负载等因素,做出性价比与稳定性最优的决策。本文将通过一些常见的选型场景推荐,为大家详细介绍阿里云服务器实例选型的最佳实践,便于大家在选择云服务器实例规格时做个参考。
|
编解码 UED
Qt侧边栏的动态切换:隐藏与显示技术详解
在现代用户界面设计中,侧边栏(Sidebar)是一个常见的组件,它为用户提供了导航和工具面板的功能。在某些应用场景下,我们可能需要动态地隐藏或显示侧边栏,以优化界面布局或提供更灵活的用户体验。本文将分享如何在Qt框架下实现侧边栏的隐藏与呈现,包括技术细节和代码示例。
1104 3
|
关系型数据库 MySQL 分布式数据库
PolarDB 与传统数据库的性能对比分析
【8月更文第27天】随着云计算技术的发展,越来越多的企业开始将数据管理和存储迁移到云端。阿里云的 PolarDB 作为一款兼容 MySQL 和 PostgreSQL 的关系型数据库服务,提供了高性能、高可用和弹性伸缩的能力。本文将从不同角度对比 PolarDB 与本地部署的传统数据库(如 MySQL、PostgreSQL)在性能上的差异。
953 1
|
数据采集 Web App开发 API
虾皮(Shopee)商品详情数据接口详解
虾皮(Shopee)是东南亚与台湾领先的电商市场,为买卖双方搭建桥梁。本文介绍如何利用网页爬虫技术获取商品详情数据,适用于无API访问权限的情况。通过Python的`requests`和`beautifulsoup4`库,可从网页中提取信息。首先需安装上述库,然后使用示例代码发送HTTP请求并解析HTML。注意遵守虾皮的服务条款,应对可能的动态内容和反爬虫措施。对于API需求,建议查阅官方文档。
550 3
|
9月前
|
存储 搜索推荐 API
淘宝拍立淘按图搜索API接口系列概述
淘宝拍立淘按图搜索API接口允许用户通过上传图片或拍摄实物来搜索相似或相同的商品。这一功能主要依赖于图像识别技术,系统会对上传的图片进行分析和处理,提取出商品的特征信息,并在淘宝的商品数据库中进行匹配搜索,最终返回与上传图片相似或相同的商品列表。
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现深度学习模型:智能环境监测与预警
【8月更文挑战第11天】 使用Python实现深度学习模型:智能环境监测与预警
1336 2
|
机器学习/深度学习 数据可视化 Python
数据分享|Python用偏最小二乘回归Partial Least Squares,PLS分析桃子近红外光谱数据可视化
数据分享|Python用偏最小二乘回归Partial Least Squares,PLS分析桃子近红外光谱数据可视化