当前位置: 首页 > news >正文

#我与Java虚拟机的故事#连载01:人在JVM,身不由己

作者:叶志远

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等特性解读应有尽有,值得期待!

推荐阅读

《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》

推荐语:这是一部从工作原理和工程实践两个维度深入剖析JVM的著作, 自2011年上市以来,前两个版本累计印刷36次,销量超过30万册,大厂面试最佳参考手册,进阶架构师必读、Java优化神书,这些标签成就了它成为原创计算机图书领域不可逾越的丰碑。

第3版在第2版的基础上做了重大修订,内容更丰富、实战性更强:根据新版JDK对内容进行了全方位的修订和升级,围绕新技术和生产实践新增逾10万字,包含近50%的全新内容,并对第2版中含糊、瑕疵和错误内容进行了修正。

你与世界

只差一个

公众号

相关文章:

  • 今天,你的模型加速了吗?这里有5个方法供你参考(附代码解析)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • 从治疗癌症到预测犯罪,细数数据科学在各领域的神奇应用
  • 入门大爆炸式发展的深度学习,你先要了解这4个最流行框架
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • Java异步编程并没有广泛使用起来,这是什么原因? (文末有福利)
  • 新书推荐 | Java核心技术 卷II 高级特性(原书第11版)
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • 中台四杰与阿里往事
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • InfoQ 编辑部开年聊聊 2020 年值得关注的十大技术趋势
  • 达摩院十大科技趋势发布:2020 非同小可!
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • flutter的key在widget list的作用以及必要性
  • JSDuck 与 AngularJS 融合技巧
  • Travix是如何部署应用程序到Kubernetes上的
  • V4L2视频输入框架概述
  • Vue2.x学习三:事件处理生命周期钩子
  • Webpack 4 学习01(基础配置)
  • 安卓应用性能调试和优化经验分享
  • 读懂package.json -- 依赖管理
  • 对超线程几个不同角度的解释
  • 番外篇1:在Windows环境下安装JDK
  • 浮现式设计
  • 给新手的新浪微博 SDK 集成教程【一】
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 前端面试总结(at, md)
  • 使用common-codec进行md5加密
  • 数组的操作
  • 1.Ext JS 建立web开发工程
  • 如何正确理解,内页权重高于首页?
  • ​Linux·i2c驱动架构​
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (k8s中)docker netty OOM问题记录
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (转) Android中ViewStub组件使用
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET CORE Aws S3 使用
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET MVC之AOP
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET关于 跳过SSL中遇到的问题
  • .NET运行机制
  • /etc/sudoer文件配置简析
  • @Transaction注解失效的几种场景(附有示例代码)
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [Angular 基础] - 自定义指令,深入学习 directive
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [C++] 多线程编程-thread::yield()-sleep_for()