凡是三年以上开发经验的人,都会在简历上写上这么一句话,了解/熟悉JVM(内存结构),对垃圾回收机制有一定的理解。
但是往往大部分人是一问三不知的,或者是没准备充分,又或者是根本就是瞎编,最起码背一下概念,说不准面试官也不会呢。
接下来的文章会围绕着JVM、JMM、垃圾回收算法、垃圾回收器、如何调优几个方面的知识来聊一下。
万里长征走出第一步。
今天我们就来看一下JVM的内存结构,虽然是概念性的知识;但凭借着理论知识,结合日常的开发工作,日积月累下来,对平时的编程影响甚广。
我这里是以JDK8为例,描述一下JVM的内存结构,如果想要了解更多更全面的知识,其实买本书看会更有效果,《深入理解Java虚拟机》。
画了一张图,先看一下!
整体来说,可以分为线程私有、线程共享两种类型,下面来看一下吧!
线程执行的字节码行号指示器,通过改变计数器的值来选取下一条要执行的字节码指令,只为Java方法计数。
因为每个线程有自己独立的行号,由于程序计数器所占内存小之又小,所以每个线程使用独立计数器来处理是说得通的,这样并不会造成什么压力,反而因为每个线程都私有一个计数器而快很多。
如果你觉得自己学习效率低,缺乏正确的指导,可以加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧! [Java架构群]
群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的JAVA交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
这也就是程序技术器是线程私有的原因。
Java方法执行时的内存模型,包含着诸多个栈帧。
栈帧是方法运行期间中的基础数据结构,每个栈帧中主要包含了局部变量、操作数栈、动态连接、返回地址等等。
虚拟机栈中存储了线程中执行方法的栈帧,只有当方法执行完毕后,栈帧才会被销毁。
这里还有一个比较重要,而且问的比较频繁的一个知识点:如何引起StackOverflowError、OutOfMemoryError异常,为什么?
这个问题我们在之后的文章中会加以讲解,大家也可以自行去研究一下。
本地方法栈与虚拟机栈的功能类似,虚拟机栈是为Java方法提供服务,而本地方法栈是为Native方法服务。
用于存储被加载的类信息、常量、静态变量等等数据。
在JDK1.8之前,这些数据存储于方法区,也就是我们常说的永久代(PermGen)。
不同于永久代占用Java虚拟机内存,元空间是直接使用本地内存存储。
更换成元空间的好处很多,比如:
字符串常量池存放在永久代中的时候,容易出现内存溢出、性能问题。
类信息的大小难以确定,因为永久代使用的是Java虚拟机内存,所以指定永久代内存时会有一定的难度。
在《深入理解Java虚拟机》一书中提到过,其他虚拟机(如:JRockit、IBM J9)等,都没有永久代。这也就说明了Java虚拟机(HotSpot)无法与其他的虚拟机进行集成搭配;当使用了元空间后,这个问题就迎刃而解了。
Java堆是所有线程共享的一块内存区域,也是Java虚拟机中所管理的最大的一块内存。
其中存储着几乎所有的对象实例,同时我们之后要说的垃圾回收机制,也是针对堆来说的,因为堆是垃圾收集器管理的主要区域。
如果根据垃圾回收集器的角度来看,堆还能分为新生代(Eden、From Survivor、To Survivor)、老年代。
这个我会在之后垃圾回收的文章里面仔细说一下,大家也可以自行查阅书籍。
以下是Java面试1—到5年以上开发必问到的面试问点,也都是一线互联网公司Java面试必备技能,下面是参照阿里年薪50W所需具备的技能图,大家可以参考下!
同时针对这12个技能,我在这整理了一份Java架构进阶面试专题PDF文档(含450题解析,包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发,设计模式,MySQL等知识点解析,内容丰富,图文结合!)
这份专题文档是免费分享的,有需要的朋友可以看向下面来获取!!
需要完整版文档的小伙伴,可以一键三连,下方获取免费领取方式!