Java 虚拟机知识答疑
本文内容来源:《深入拆解 Java 虚拟机》
我相信在不少程序员的观念里,Java 虚拟机是透明的。在他们看来,我们仅需知道 Java 核心类库,以及第三方类库里 API 的用法,便可以专注于实现具体业务,并且依赖 Java 虚拟机自动执行乃至优化我们的应用程序。
那么,我们还需要了解 Java 虚拟机吗?
我开设了《深入拆解 Java 虚拟机》专栏,得到了 20000+ 程序员的订阅,我想这个答案是不言而喻的:大家渴望去了解底层,迫切想“知其然且知其所以然”。
经过三专栏完结了,希望大家对 Java 虚拟机的学习不要停止,因为还有更深入更有趣的内容待你去挖掘。但同时我也发现,大家学习 JVM 的过程中也遇到了很多问题,我特意做了一个答疑的专题:六问 Java 虚拟机,带你再深入 JVM 底层。
点击“阅读原文”,查看整个专题内容

在编译生成的 Java 字节码中,每个方法都附带一个异常表。异常表中的每一行均定义了一条异常执行路径,其中包括规定捕获范围的起始字节码索引、终止(不包含)字节码索引,异常处理代码的起始字节码索引,以及所捕获的异常类型。
当程序触发异常时,JVM 会从上至下遍历异常表中的所有条目。当触发异常的字节码的索引值在某行异常表条目的捕获范围内,JVM 会判断所抛出的异常和该条目想要捕获的异常是否匹配。如果匹配,JVM 会将控制流转移至该条目所指向的异常处理代码。
上述异常捕获机制还被用于 finally 从句的实现。通常,Java 程序的编译器 javac 会复制多份 finally 代码块,放置于生成的 Java 字节码之中,然后通过生成多行异常表条目,来实现完整的 finally 逻辑。
相关文章「JVM 是如何处理异常的?」

默认情况下,反射调用首先会被委派给 native 方法来进行。可想而知,其运行效率低下。当某个反射调用的调用次数达到 15 之后,JDK 代码断定该调用属于热点调用。继而,JDK 将动态生成直接调用目标方法的字节码,并将反射调用的委派对象由原本的 native 方法实现切换至该动态生成的实现。这种方式的运行效率相对于 native 方法来说要高很多。
之所以 JDK 不从一开始便采用动态生成字节码的方式,主要是因为生成过程需要耗费一定的时间。对于那些整个生命周期中仅执行数次的反射调用,动态生成字节码将得不偿失。
然而,即便是直接调用目标方法的动态实现,其峰值性能也无法跟真正的直接调用相媲美。这背后涉及到即时编译中的虚方法内联。
相关文章「JVM 是如何实现反射的?」
相关文章「 方法内联(下)」

目前 JVM 的主流垃圾回收器采取的都是可达性分析算法。该算法的实质是将一系列被称为 GC Roots 的对象作为初始的存活对象合集,然后从该合集出发探索所有能够被该集合引用到的对象,并标记为存活对象。当标记阶段结束之后,未被标记到的对象便是可以清除的。
传统的垃圾回收算法在标记、清除过程中需要中止其他应用线程,即所谓的 Stop-The-World。新型的垃圾回收算法,如 CMS、G1 以及 ZGC,尽可能地实现并发标记、清除,从而让 Stop-The-World 的时间长度可控。
垃圾回收的另一基础思想则是分代回收。JVM 会将新生成的对象划为新生代,而将在多次垃圾回收中存活下来的对象划为老年代。JVM 会为不同的分代设置不同的回收算法,从而达到新生代多收集、快收集,老年代少收集、全收集的目标。
相关文章「 垃圾回收(上)」

点击“阅读原文”,查看完整专题内容
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平同马克龙交流互动的经典瞬间 7904858
- 2 解放军潜艇罕见集群机动 7809197
- 3 公考枪手替考89次敛财千万 7712736
- 4 2025你的消费习惯“更新”了吗 7618198
- 5 危险信号!俄数百辆保时捷突然被锁死 7520359
- 6 日本在与那国岛挖一锹土我军都能发现 7427114
- 7 连霍高速发生交通事故 造成9死7伤 7330459
- 8 今日大雪 要做这些事 7234408
- 9 15岁高中生捐赠南京大屠杀日军罪证 7140302
- 10 中疾控流感防治七问七答 7040177







InfoQ
