从一无所知到无所不知————jvm系列(2)

目录

前文回顾

一、存放类的方法区

1.类型信息指加载的类型(类、接口、枚举、注解)

二、执行代码指令用的程序计数器

三、Java虚拟机栈

四、Java堆内存

五、流程图

六、其他内存区域

结尾


前文回顾


上一篇文章我们聊了在什么情况下会触发类的加载?加载之后的验证、准备和解析分别是干什么的?其中尤为重要的是准备阶段和初始化阶段,是如何为类分配内存空间的?然后类加载器的规则是什么?

一、存放类的方法区

这个方法区是在JDK 1.8以前的版本里,代表JVM中的一块区域,在JDK 1.8以后,这块区域的名字改了,叫做“Metaspace”。
方法区中存放的是类型信息、常量、静态变量、即时编译器编译后的代码缓存、域信息、方法信息等。

1.类型信息指加载的类型(类、接口、枚举、注解)

①这个类型的全局限定名
②这个类型直接父类的全局限定名(interface与Java.lang.Object没有父类)
③这个类型的访问权限修饰符
④这个类型直接接口的有序列表

二、执行代码指令用的程序计数器


程序计数器就是用来记录当前执行的字节码指令的位置的,也就是记录目前执行到了哪一条字节码指令。
注意,每个线程都会有自己的一个程序计数器,专门记录当前这个线程目前执行到了哪一条字节码指令了

三、Java虚拟机栈


Java虚拟机栈,是来保存每个方法内的局部变量等数据的,每个线程都有自己的Java虚拟机栈,
如果线程执行了一个方法,就会对这个方法调用创建对应的一个栈帧,栈帧里有这个方法的局部变量表 、操作数栈、动态链接、方法出口等东西。


压栈与出栈
当一个栈帧对应的A方法中调用了另一个B方法,这个B方法里也有自己的局部变量,那么这个时候会给这个B方法又创建一个栈帧,压入线程的Java虚拟机栈里。
接着如果B方法执行完毕,B方法对应的栈帧就会从Java虚拟机栈中弹出。

四、Java堆内存

存放的是我们new出来的对象,声明的对象类型指向的就是堆中这个实例的地址。

五、流程图

六、其他内存区域

其实在JDK很多底层API里,比如IO相关的,NIO相关的,网络Socket相关的如果大家去看他内部的源码,会发现很多地方都不是Java代码了,而是走的native方法去调用本地操作系统里面的一些方法,可能调用的都是c语言写的方法,或者一些底层类库比如下面这样的:
public native int hashCode();

在调用这种native方法的时候,就会有线程对应的本地方法栈,这个里面也是跟Java虚拟机栈类似的,也是存放各种native方法的局部变量表之类的信息。还有一个区域,是不属于JVM的,通过NIO中的allocateDirect这种API,可以在Java堆外分配内存空间。然后,通过Java虚拟机里的DirectByteBuffer来引用和操作堆外内存空间。其实很多技术都会用这种方式,因为有一些场景下,堆外内存分配可以提升性能。


结尾

给大家留个思考题
在Java堆内存中分配的那些对象,到底会占用多少内存?一般怎么来计算和估算系统创建的对象对内存占用的压力呢?


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值