课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
随着互联网的不断发展,越来越多的新手程序员都开始接触和学习java编程来实现互联网开发的入门技术语言,下面我们就一起来了解一下,关于java编程都有哪些常见的问题。
Java是如何在保证可移植性的前提下提供高执行效率的?
Java程序为常见的执行方式,是预先编译为一种名为Java字节码的中间代码格式。这种代码格式无法直接运行在CPU之上,而是需要借助JVM来执行。换句话说,只要某个平台提供了合乎JVM规范的实现,它便能执行这份Java字节码。这也就是我们经常说的“一次编写,到处运行”。
主流的OpenJDK/OracleJDK中所提供的JVM叫做HotSpot。它同时采用了解释执行和即时编译。解释执行就好比同声传译,JVM一边理解输入的字节码一边向CPU发出指令序列;即时编译则是“磨刀不误砍柴工”,JVM会在运行过程中将热点代码编译成为可直接执行的二进制代码。
这种混合执行模式是建立在程序符合二八定律的假设上,即百分之二十的代码占据了百分之八十的计算资源。对于不常用代码,我们无需耗费时间将其编译成二进制代码,而是采取解释执行的方式运行;另一方面,对于仅占据小部分的热点代码,JVM则会花费时间将其编译为二进制代码,以达到理想的运行效率。
异常捕获是如何实现的?
在编译生成的Java字节码中,每个方法都附带一个异常表。异常表中的每一行均定义了一条异常执行路径,其中包括规定捕获范围的起始字节码索引、终止(不包含)字节码索引,异常处理代码的起始字节码索引,以及所捕获的异常类型。
当程序触发异常时,JVM会从上至下遍历异常表中的所有条目。当触发异常的字节码的索引值在某行异常表条目的捕获范围内,JVM会判断所抛出的异常和该条目想要捕获的异常是否匹配。如果匹配,JVM会将控制流转移至该条目所指向的异常处理代码。
上述异常捕获机制还被用于finally从句的实现。通常,Java程序的编译器javac会复制多份finally代码块,放置于生成的Java字节码之中,然后通过生成多行异常表条目,来实现完整的finally逻辑。
反射调用为什么慢?
默认情况下,反射调用先会被委派给native方法来进行。可想而知,其运行效率低下。当某个反射调用的调用次数达到15之后,JDK代码断定该调用属于热点调用。继而,JDK将动态生成直接调用目标方法的字节码,并将反射调用的委派对象由原本的native方法实现切换至该动态生成的实现。这种方式的运行效率相对于native方法来说要高很多。
之所以JDK不从一开始便采用动态生成字节码的方式,主要是因为生成过程需要耗费一定的时间。对于那些整个生命周期中仅执行数次的反射调用,动态生成字节码将得不偿失。
然而,即便是直接调用目标方法的动态实现,其峰值性能也无法跟真正的直接调用相媲美。这背后涉及到即时编译中的虚方法内联。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!