面试官问你Java内存区域你用new创建对象来解释

这几天研究Java虚拟机(Java Virtual Machine),不得不说,这玩意真牛掰,Java跨平台真不是盖的,JVM的学习,今天就从内存区域开始,Java虚拟机他有自己管理的一块内存区域,并且把这块区域分成了若干个小区域,来一张图,先看看葫芦里装的都是啥
在这里插入图片描述
程序计数器
这五块区域,我们逐个进行击破,先来第一个程序计数器,听这家伙的名字都能大致猜出来他是干啥的,计数的呗,给谁计数呀,给程序计数的,当我们运行一段程序的时候,一步一步的执行,如果在执行的过程中,调用了某个方法,那么就进入到该方法中执行,执行完该方法后,还能接着往后执行,这么的精确无误,是谁的功劳,别找别人,程序计数器是头等功劳,程序计数器可以看做是当钱线程所执行的字节码的行号指示器,他是服务于当前线程的,可不是线程共享的,要是线程共享了,估计这程序跑着跑着都乱套了,每一个线程都会有自己的程序计数器,即是线程私有。
虚拟机栈
与程序计数器一样,也是线程私有的。虚拟机栈,故名思意,是一块栈内存,这里面主要存放有,方法中定义的基本数据类型、对象引用、方法出口等信息。当某个方法被执行的时候,虚拟机会同步创建一个栈帧,用于存储这些信息。每个方法的执行到执行完毕,就对应着,栈帧在虚拟机栈中进栈和出栈的过程。说到这里,你还可以给面试官撤一点关于异常的问题,例如,当线程请求的栈的深度,大于虚拟机所允许的深度时,就会抛出StackOverflowError异常(栈溢出),还有如果虚拟机栈容量是可以扩展的,那么当栈扩展的时候,无法申请到足够的空间,会抛出OutOfMemoryError异常(内存不足)。
本地方法栈
本地方法栈也是线程私有的。说实话,本地方法栈跟虚拟机栈的区别除了名字还有啥,二者的作用很相似,JVM分的还真够细的,既然如此,肯定还是有点区别的,故名思意,本地方法栈嘛,肯定是为本地(Native)方法服务的呀,而虚拟机栈是为Java方法(也就是字节码)服务的,我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。与虚拟机栈一样,也会抛出StackOverflowError异常和OutOfMemoryError异常。

三个线程私有的区域说完了,下面这俩是线程共享的区域,堆内存的是干啥的呢,是用来存放对象的实例的,目前所有对象的实例都是在这里分配内存的,当然了,这也是虚拟机所管理的最大的一块内存区域,这块区域详细说明的话,是垃圾收集器所管理的内存区域,也就是我们常听到的GC堆(Garbage Collected Heap,强调说明不是垃圾堆而是GC堆),堆内存是可以扩展的,当在堆实例分配内存的时候,内存无法扩展时,会抛出OutOfMemoryError异常。
方法区
方法区也是一块共享的区域,他主要用于存储对象类型数据,像类型信息、常量、静态变量等,在方法区中有一块重要的组成部分,就是我们的常量池,常量池就在方法区中的。
new关键字创建对象
当我们用new关键字创建对象的时候,我们知道会创建一个或两个对象。首先会看看常量池中是否存在,如果不存在,需要创建一个,如果存在了,那就不用在这里创建了,常量池中为什么要存在这么个对象呢,原因就是为了存储对象类型信息,然后还会在堆中创建一个对象这里用于存储对象的实例,该堆内存中还有一个对象类型的指针->指向方法区中的->常量池中的->对象类型数据,同时虚拟机也同步创建了一个栈帧,把这些信息封装起来进栈,栈中也有一个指向->堆内存的地址。这样一来,当程序计数器执行到某个方法时,首先通过中的地址定位到中的实例数据,然后定位到方法区中的类型数据。

发布了464 篇原创文章 · 获赞 317 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/HeZhiYing_/article/details/105245335