- 浏览: 3037056 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
有人问下面这段代码里,main()方法里的outer.new Inner()部分为什么会生成了一个对outer.getClass()的调用:
javac编译它生成的main方法的代码是:
其中,对应outer.new Inner()的部分是:
可以看到里面有一处对outer.getClass()的调用,然而得到的结果却马上被pop指令抛弃掉了。
这个问题通过调试javac很容易解决。调试javac的方法可以参考以前一帖。
设置好调试环境后,在调试器里把上面的代码交给javac去编译。
简单猜测就可以知道,生成的对outer.getClass()方法的调用是在最终生成代码的时候才做的,而不是在更早阶段被解除的语法糖,所以我们要注意的目标就是com.sun.tools.javac.jvm.Gen类,其中的visitNewClass(JCNewClass tree)方法。
在这个方法设上断点,然后开始调试。
第一次碰到断点会是main()方法里的new Outer(),这个跳过。
然后第二次进来的时候,观察调试器的变量窗口,可以看到:
从javac的角度来看,源码里的
被改写成了这种形式:
(内部类被改名和改写为顶层类、隐式的外部类参数改写为显式参数)
接下来,有趣的点就是那个<*nullchk*>注释。
传给Inner()构造器的实际参数并不是原本的outer局部变量,而是outer局部变量外加一个空指针检查——要的值还是outer的值,不过如果outer为null的话,这里要抛出NullPointerException。
从javac的角度看,直接读outer局部变量可以用一个JCTree.JCIdent节点来表示,而这里则多包装了一个tag为JCTree.NULLCHK的JCTree.JCUnary节点。
正是在生成这个outer<*nullchk*>节点的代码时,会执行到Gen.visitUnary()的下述部分:
其中的genNullCheck()是:
也就是说那个对getClass()的调用只不过是借invokevirtual指令来帮忙做null检查而已。getClass()本身得到的值其实是没用到的。
这个行为在Java语言规范里有相应的规定。在Java语言规范第三版,
15.9.2 Determining Enclosing Instances
该小节规定了应该使用什么对象作为外部类的实例
15.9.3 Choosing the Constructor and its Arguments
该小节规定了外部类实例在参数列表中的位置
15.9.4 Run-time Evaluation of Class Instance Creation Expressions
该小节规定了上面提到的空指针检查的行为:
规范里明确了“要抛出NullPointerException”的行为,至于是如何实现null检查的则没规定,可以由实现自由发挥。用普通的if...else来做这个检查当然也可以,只不过生成的字节码就比调用getClass()的办法更长一些。
====================================================================
无独有偶,ECJ(Eclipse Compiler for Java)在编译这种代码的时候同样会生成对getClass()方法的调用:
这当然不是偶然,因为getClass()方法是在Object上声明的(因此所有对象上必然存在),而且是final的(保证了它有确定的行为),而且运行开销比较低。
同样是Object上声明的方法,toString()、hashCode()之类其实也可以用,但它们都不是final的,有潜在可能性会引发较大的运行开销;这么分析一圈下来,Object上最好用的就剩下getClass()了。
public class Outer { public class Inner { } public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); } }
javac编译它生成的main方法的代码是:
public static void main(java.lang.String[]); Code: Stack=4, Locals=3, Args_size=1 0: new #2; //class Outer 3: dup 4: invokespecial #3; //Method "<init>":()V 7: astore_1 8: new #4; //class Outer$Inner 11: dup 12: aload_1 13: dup 14: invokevirtual #5; //Method java/lang/Object.getClass:()Ljava/lang/Class; 17: pop 18: invokespecial #6; //Method Outer$Inner."<init>":(LOuter;)V 21: astore_2 22: return LineNumberTable: line 4: 0 line 5: 8 line 6: 22
其中,对应outer.new Inner()的部分是:
8: new #4; //class Outer$Inner 11: dup 12: aload_1 13: dup 14: invokevirtual #5; //Method java/lang/Object.getClass:()Ljava/lang/Class; 17: pop 18: invokespecial #6; //Method Outer$Inner."<init>":(LOuter;)V
可以看到里面有一处对outer.getClass()的调用,然而得到的结果却马上被pop指令抛弃掉了。
这个问题通过调试javac很容易解决。调试javac的方法可以参考以前一帖。
设置好调试环境后,在调试器里把上面的代码交给javac去编译。
简单猜测就可以知道,生成的对outer.getClass()方法的调用是在最终生成代码的时候才做的,而不是在更早阶段被解除的语法糖,所以我们要注意的目标就是com.sun.tools.javac.jvm.Gen类,其中的visitNewClass(JCNewClass tree)方法。
在这个方法设上断点,然后开始调试。
第一次碰到断点会是main()方法里的new Outer(),这个跳过。
然后第二次进来的时候,观察调试器的变量窗口,可以看到:
从javac的角度来看,源码里的
outer.new Inner()
被改写成了这种形式:
new Outer$Inner(outer<*nullchk*>)
(内部类被改名和改写为顶层类、隐式的外部类参数改写为显式参数)
接下来,有趣的点就是那个<*nullchk*>注释。
传给Inner()构造器的实际参数并不是原本的outer局部变量,而是outer局部变量外加一个空指针检查——要的值还是outer的值,不过如果outer为null的话,这里要抛出NullPointerException。
从javac的角度看,直接读outer局部变量可以用一个JCTree.JCIdent节点来表示,而这里则多包装了一个tag为JCTree.NULLCHK的JCTree.JCUnary节点。
正是在生成这个outer<*nullchk*>节点的代码时,会执行到Gen.visitUnary()的下述部分:
public void visitUnary(JCUnary tree) { // ... Item od = genExpr(tree.arg, operator.type.getParameterTypes().head); switch (tree.tag) { // ... case JCTree.NULLCHK: result = od.load(); code.emitop0(dup); genNullCheck(tree.pos()); break; } }
其中的genNullCheck()是:
/** Generate a null check from the object value at stack top. */ private void genNullCheck(DiagnosticPosition pos) { callMethod(pos, syms.objectType, names.getClass, List.<Type>nil(), false); code.emitop0(pop); }
也就是说那个对getClass()的调用只不过是借invokevirtual指令来帮忙做null检查而已。getClass()本身得到的值其实是没用到的。
这个行为在Java语言规范里有相应的规定。在Java语言规范第三版,
15.9.2 Determining Enclosing Instances
该小节规定了应该使用什么对象作为外部类的实例
15.9.3 Choosing the Constructor and its Arguments
该小节规定了外部类实例在参数列表中的位置
15.9.4 Run-time Evaluation of Class Instance Creation Expressions
该小节规定了上面提到的空指针检查的行为:
Java Language Specification, 3rd Edition 写道
At run time, evaluation of a class instance creation expression is as follows.
First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.
First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.
规范里明确了“要抛出NullPointerException”的行为,至于是如何实现null检查的则没规定,可以由实现自由发挥。用普通的if...else来做这个检查当然也可以,只不过生成的字节码就比调用getClass()的办法更长一些。
====================================================================
无独有偶,ECJ(Eclipse Compiler for Java)在编译这种代码的时候同样会生成对getClass()方法的调用:
public static void main(java.lang.String[]); Code: Stack=3, Locals=2, Args_size=1 0: new #1; //class Outer 3: dup 4: invokespecial #13; //Method "<init>":()V 7: astore_1 8: new #14; //class Outer$Inner 11: aload_1 12: dup 13: invokevirtual #16; //Method java/lang/Object.getClass:()Ljava/lang/Class; 16: pop 17: invokespeci8al #20; //Method Outer$Inner."<init>":(LOuter;)V 20: return LineNumberTable: line 4: 0 line 5: 8 line 6: 20
这当然不是偶然,因为getClass()方法是在Object上声明的(因此所有对象上必然存在),而且是final的(保证了它有确定的行为),而且运行开销比较低。
同样是Object上声明的方法,toString()、hashCode()之类其实也可以用,但它们都不是final的,有潜在可能性会引发较大的运行开销;这么分析一圈下来,Object上最好用的就剩下getClass()了。
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16227以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10435先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
基于LLVM实现VM的JIT的一些痛点
2014-01-07 17:25 0同事Philip Reames Sanjoy Das http ... -
《自制编程语言》的一些笔记
2013-11-24 00:20 0http://kmaebashi.com/programmer ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22341(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21835之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
oop、klass、handle的关系
2013-07-30 17:34 0oopDesc及其子类的实例 oop : oopDesc* ... -
Nashorn各种笔记
2013-07-15 17:03 0http://bits.netbeans.org/netbea ...
相关推荐
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
【数据结构】《数据结构》经典算法代码.zip 栈 待更新 队列 括号匹配(搞定) 用栈实现递归式的非递归代码P90 树 的考察在于各种树的特点,以及树的遍历算法 先序 递归 非递归 后序 递归 非递归 中序 递归 非递归 层序 线索化 求二叉树的高度 递归 非递归 平衡二叉树 判断一棵树是否为平衡二叉树 (2019-9-6)
Microsoft Remote Desktop for mac
Axelrod-1.10.0-py2.py3-none-any.whl.zip
最新源支付系统源码 ∨7版全开源 免授权 附详细撘建教程 站长亲测YPay是专为个人站长打造的聚合免签系统,拥有卓越的性能和丰富的功能。它采用全新轻量化的界面U!,让您能更方便快捷地解决知识付费和运营赞助的难题。同时,它基于高性能的thinkphp 6.1.4+layui2.9.3+PearAdmin架构,提供实时监控和管理功能,让您随时随地掌握系统运营情况。 运行环境 Nignx/Apache/llS PHP 8.1 Mysql 5.6 ~ 5.7 Redis Supervison
基于JSP的图书管理系统 项目简介 本项目是一个基于JSP的图书管理系统,旨在提供一个简单的图书管理解决方案。系统包含了图书信息管理、借阅信息管理、读者信息管理以及用户认证等核心功能。 功能模块 图书信息管理 book.java: 定义了一个图书对象的属性及其对应的getter和setter方法。包含图书编号、图书名称、作者、出版社、价格、类型编号和备注等属性。 借阅信息管理 borrow.java: 表示借款信息相关的Bean,包含借款编号、图书编号、借款日期、还款日期、实际还款日期、借款金额和借款状态等属性。 读者信息管理 Reader.java: 代表一个读者对象,包含读者编号、姓名、性别、部门、联系电话、身份证号码、读者类型、创建时间和状态等属性。 用户认证 USER.java: 简单的用户信息类,包含用户名和密码两个属性,并提供对应的getter和setter方法。 字符编码过滤 CharFilter.java: 一个Servlet过滤器,用于处理字符编码问题,确保请求中的字符数据以UTF8编码进行处理。 技术栈 编
Axelrod-1.17.1-py2.py3-none-any.whl.zip
【测试环境】 windows10 anaconda3+python3.8 torch==1.9.0+cu111 ultralytics==8.2.70 【模型可以检测出类别】 Bad Good Unripe 更多实现细节参考博文:https://blog.csdn.net/FL1623863129/article/details/141931442
基于Spring Boot框架的OA管理系统 项目简介 本项目是一个基于Spring Boot框架开发的OA管理系统,专注于提供高效、稳定的企业办公自动化解决方案。系统集成了用户管理、安全控制、数据处理和报表生成等功能,旨在提升企业内部管理效率和数据处理能力。 主要功能 用户管理 用户信息管理通过UserInfo类管理用户的基本信息,包括账号、姓名、密码、电子邮件等。 用户状态管理支持用户账号的启用和禁用,以及用户信息的删除标记。 安全控制 登录认证通过SecurityController实现用户登录功能,包括账号验证、密码检查和状态判断。 数据访问控制通过SecurityMapper和SecurityService实现用户信息的数据库查询和业务逻辑处理。 数据处理 分页处理通过PageUtils工具类实现数据的分页显示,支持动态页码处理。 Excel报表生成通过ExcelUtils工具类生成Excel报表,支持自定义表头和内容。 错误处理 API响应处理通过BitResult类统一处理API调用的结果,包括操作成功与否、数据和错误信息
基于Spring Boot框架的微信课程学习系统 项目概述 本项目是一个基于Spring Boot框架开发的微信课程学习系统,专注于提供丰富的课程资源和学习互动功能。系统集成了微信消息处理、课程管理、用户签到、试卷管理等多个模块,旨在为学生和教师提供一个高效、便捷的学习和教学环境。 功能模块 微信消息处理 基础事件处理处理微信事件的基本信息,如消息的发送方和接收方、消息创建时间、消息类型和事件类型等。 地理位置事件存储和处理用户的地理位置信息,用于签到和位置相关的功能。 菜单事件处理微信自定义菜单相关的事件,如点击菜单按钮后的响应。 二维码事件处理扫描二维码相关的事件,包括事件的标识和换取二维码所需的票据。 关注事件处理微信中的关注或取消关注事件。 课程管理 资源上传教师可以上传课程资源,如文档、视频等。 课程论坛学生和教师可以在课程论坛中进行讨论和互动。 申请入班学生可以申请加入班级,教师可以审核学生的申请。 用户签到 签到功能学生可以通过系统进行签到,记录签到时间和位置。 签到详情教师可以查看学生的签到详情,包括签到时间和位置。
IMG_20240905_192349.jpg
Avanza-0.0.11-py3-none-any.whl.zip
本项目旨在开发一个用于 Linux 的 Shell 程序,利用 C++ 标准库和 Linux 系统调用来实现。该 Shell 程序提供了基本的命令执行功能,支持 I/O 重定向和管道操作,并实现了一些内置命令
。支持yolov5s,yolov5m,yolov5l.zip目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
byoc框架中代码生成部分文档,包括生成C代码和JSON格式
QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。
wireshark-4.2.4
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
qss
Access client