给我一个CPU,给我一块内存,我来执行一段代码。
我要如何分配呢?
new User();
这里有一个有一个User类,如果我要new出来User对象,必须先知道它长什么样子,我先搞一块区域出来,把User类的样子给存下来。
可以把“User类的样子” 比作造房子的“图纸”或者“模板”;
这块区域命名为方法区。
那方法区应该保存类的哪些信息呢?
我想一下,应该是只要程序运行时需要用到的类的数据都要保存下来吧。
比如,类型信息、方法信息,常量、静态变量、即时编译器编译后的代码缓存等数据。
既然这个区域要把所有的类的信息都记录下来,每个线程都可能需要这些信息的,那就是要让所有线程都能访问的。
new User();
然后是要new一个新的User类对象,我先从方法区获取User类信息,再新建这个对象,再直接在内存里存起来不就好了,但是如果我下次想要获取这个对象,好像就没办法找到,因为只是分配了内存给这个新对象,却没有记录这个实例对象的任何信息,所以没办法获取到这个对象,这种方式行不通。
于是有了这种写法
User user1 = new User();
这样好像合理了很多,user1存储了新建的User类对象的地址值,这样我只要知道记住引用变量user1,就能知道我新建的User类对象了。
User user1 = new User();
=号前面的部分和=号后面的部分,这两个部分的功能不一样,最好给他们分类,放在不一样的地方存放。
=号前面的部分放置区域叫虚拟机栈,具体是放在虚拟机栈的栈帧中。
每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
局部变量表:存放方法参数和方法内定义的局部变量
操作数栈:存放被操作数据的栈结构,1+2对应的操作数栈是1,2。
动态链接:动态链接的作用就是为了将这些符号引用转换位调用方法的直接引用。
方法出口:正常完成出口,异常完成出口
为什么前面要强调是虚拟机栈呢,因为还有个本地方法栈,java语言中有native修饰的本地方法,其调用的可能就是c,c++语言写的方法,而不是java方法,因此才又分出来一个区域,但是他们的作用是非常相似的。
=号后面的部分放置区域叫堆,主要是用来放实例的数据的。
方法的是通过压栈和弹栈的方式来执行的。
线程之间的执行是通过抢占CPU时间片资源的,因此线程之间会不断的切换,还要划分一块区域出来专门存储线程执行的进度,要不然下次切换回来都不知道要从哪个地方继续了。
这块区域叫PC寄存器,也可以叫程序计数器。
上图红色区域为线程共享的,其他为线程私有的。
下一个章节,会讲解堆区的分配及原因和垃圾回收机制,可以点个关注!!!
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!