JVM——内存区域与内存溢出

目录

运行时数据区

 PC寄存器

使用PC寄存器存储字节码指令地址有什么用呢?为什么使用PC寄存器记录当前线程的执行地址呢?

PC寄存器为什么被设定为线程私有

 虚拟机栈

局部变量

静态变量(类变量)和局部变量的对比

举例栈溢出的情况?

通过调整栈的大小就能保证不出现溢出现象吗?

分配栈的内存越大越好吗?

垃圾回收是否会设计虚拟机栈吗?

方法中定义的局部变量是否线程安全?

本地方法栈

 堆是分配空间的唯一选择吗?

方法区

​编辑 永久代(1.7及以前)为什么被元空间替换

 运行时常量池

对象实例化的六种方式:

对象创建的步骤


运行时数据区

 在Java虚拟机的运行时数据区种,红色部分的是随着虚拟机的创建而创建,随着虚拟机的销毁而销毁,而灰色部分是每个线程一份

 PC寄存器

PC寄存器用来存储指向下一条指令的地址。也即将执行的指令代码,有执行引擎读取下一条指令。与线程生命周期一致。

使用PC寄存器存储字节码指令地址有什么用呢?为什么使用PC寄存器记录当前线程的执行地址呢?

因为CPU需要不停的切换各个线程,这时候切换回来以后,就得直到接着从哪开始继续执行。JVM字节码解释器的值来明确下一条应该执行什么样的字节码指令。

PC寄存器为什么被设定为线程私有

 虚拟机栈

主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。

每逢线程创建的时候都会创建一个虚拟机栈,虚拟机栈里面保存的是一个个的栈帧,一个栈帧就对应一个Java方法的调用。每个方法被调用直至执行完毕,就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量

保存的8中基本数据类型、对象的引用地址。

 这也就是为什么在静态方法中不能应用this变量,因为在静态方法的局部变量表的局部变量槽中没有放该数据;而构造方法和实例方法中的局部变量槽的Index为0的位置是放了this。

静态变量(类变量)和局部变量的对比

 变量的分类:

按照数据类型分:①基本数据类型 ②引用数据类型

按照类中声明的位置分:①成员变量:都经历过默认初始化阶段

       类变量(静态变量):linking的prepare阶段:给类变量默认赋值->initial阶段进行显式赋值

       实例变量:随着对象的创建会在堆空间中分配实例变量空间,并进行默认赋值

                                        ②局部变量:在使用前必须进行显示赋值,否则编译不通过

举例栈溢出的情况?

StackOverFlowError:通过-xss设置栈的大小,可以设置为固定大小和动态大小,固定大小的情况下不断加栈帧会导致栈溢出。

通过调整栈的大小就能保证不出现溢出现象吗?

不能保证。只能是让StackOverFlowError出现的更晚。

分配栈的内存越大越好吗?

不是,因为

垃圾回收是否会设计虚拟机栈吗?

不会。只有进栈出栈。

方法中定义的局部变量是否线程安全?

具体问题具体分析:

例如:使用线程不安全的类StringBuilder(内部没有加同步锁)来举例子,不然如果使用StringBuffer,本身就是线程安全的就没意义了

在method1里面的s1是线程安全的。因为一个线程操作这个数据。

例子二:这里的StringBuilder是以参数的形式传入的

 sBuilder操作的过程是线程不安全的,因为该对象的引用地址是以参数形式传进来,并不是单独保存在该线程里面,所以是线程不安全的

本地方法栈

Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用

一个Java程序启动的时候就会创建一个Java虚拟机实例,一个Java虚拟机实例里面只存在一个堆空间。

线程共享的堆可以划分出多个线程私有的分配缓冲区TLAB,以提升对象分配时的效率。

(几乎)所有的对象实例以及数组都应当在运行时分配在堆上。

 堆是分配空间的唯一选择吗?

方法区

是各个线程共享的内存区域,用于存储被虚拟机加载的

类型信息常量、静态变量即时编译器编译后的代码缓存等数据。 

 

 永久代(1.7及以前)为什么被元空间替换

 运行时常量池

用于存放编译时期生成的各种字面量与符号引用(例如字面量String、System),这部分内容将在类加载后存放到方法区的运行时常量池中。

运行时常量池中包含多种不同的变量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用,此时不再是常量池中的符号地址了,这里换为真实地址。

对象实例化的六种方式:

对象创建的步骤

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值