作者: 叶志远
Java自上世纪90年代问世以来,以其优良的特性,逐渐占据了企业级开发的主流位置,并且日益强大的语言生态,更加巩固了它在编程语言排行榜上的地位。
Java的快速发展,得益于支撑它运行的底层平台:JVM,这个由C++编写的虚拟机,有着一个抽象化的虚拟机体系结构,让我们的Java程序得以“一次编写,到处运行”,并且开发人员并不需要关心资源问题,JVM为我们独挑大梁。但是,正如周志明老师在《深入理解Java虚拟机》中所说:“ Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的「高墙」,墙外面的人想进去,墙里面的人却想出来 ”,技术总是让你得到你想得到的,但你却不得不丢弃一些东西。是的,在Java的道路上,“入之愈深,其进愈难,而其见愈奇”,当你在手舞足蹈地庆祝Java带给你的便利的同时,你也可能苦恼于内存泄漏和溢出的问题,有道是: 人在JVM,身不由己。
枕边的那本第一版《深入理解Java虚拟机》是我在大学时期买的,现在基本快翻烂了,记得刚毕业的时候,上下班两个小时地铁的通勤时间,总喜欢捧着它结合白天系统的问题寻找答案,那段时光,是我毕业之后最美好的回忆。依稀还记得技术生涯当中处理的第一个JVM问题,当时我的应用程序构建于JDK1.6,基于POI做了一个Excel报表导出的功能,第一次部署的时候使用的默认JVM参数,但是测试人员在点击了一次导出之后,其他功能就疑似挂掉了,过了一会后才能正常使用;再点击导出,又出现这个问题,查看堆栈发现错误信息:java.lang.OutOfmemoryError: PermGen Space,由于当时刚毕业,对于这种疑难问题没有经验,一时间慌了神,后面我猛然想起《深入理解Java虚拟机》中提到过类似的场景,在JDK1.6以及之前的版本中,常量池分配在永久代内,而导出Excel报表这个功能是会产生大量的字符串的,而字符串分配在字符串常量池,原来是一次导出产生的字符串撑爆了永久代!按照书里的提示,我只需要将永久代设置大一些,就不会出现这种现象。随即设置了XX:PermSize和XX:MaxPermSize的值,完美解决了这个问题。至今想起这个事件,仍然很庆幸当时买了《深入理解Java虚拟机》,从此以后,我就将它放在枕头下了。
如今,毕业参加工作已有好几年了,也会时常翻阅《深入理解Java虚拟机》,争取对每个细节做到知根知底。从新生代到老年代,从YGC到FGC,从CMS到G1,无不是Java开发者老生常谈的话题。从2017年到2019年,两年时间Oracle发布了Java9到Java13,似乎感觉快跟不上技术发展的脚步了,好像Java8的Lambda还没学透,Java9的模块化就来了,Java10的var变量类型推断就来了,Java11的ZGC就来了…再一次地,我想起了跟随《深入理解Java虚拟机》的脚步,得知第三版已出版,相比老版新增内容多到50%,JDK12和JDK13 EA等特性解读应有尽有,值得期待!
推荐阅读
推荐语: 这是一部从工作原理和工程实践两个维度深入剖析JVM的著作, 自2011年上市以来,前两个版本累计印刷36次,销量超过30万册,大厂面试最佳参考手册,进阶架构师必读、Java优化神书,这些标签成就了它成为原创计算机图书领域不可逾越的丰碑。
第3版在第2版的基础上做了重大修订,内容更丰富、实战性更强:根据新版JDK对内容进行了全方位的修订和升级,围绕新技术和生产实践新增逾10万字,包含近50%的全新内容,并对第2版中含糊、瑕疵和错误内容进行了修正。