JVM虚拟机之Java内存区域与内存溢出异常

目录

1、程序计数器(也叫PC寄存器)

面试常问问题:

2、Java虚拟机栈

2.1虚拟机栈中常见异常和栈大小的设置方法

 2.2栈帧的内部结构

 局部变量表(本地变量表)

2.2Java虚拟机栈的五到面试题

3、Java堆 

 3.1TLAB

 3.2堆空间参数的设置

 3.3堆是分配对象存储的唯一选择吗?

 4、方法区

4.1栈、堆、方法区交互关系

 5、运行时常量池

 6、运行时数据区常见面试题


 Java虚拟机运行时数据区如图所示:

其中红色部分为所有线程共享的数据区,即所有线程都访问这个数据区。灰色的为线程隔离的数据区,即每个线程都会维护一个自己的这个数据区。Java堆、方法区对于一个进程来说他们各自是唯一的。Java程序运行起来之后就是对应一个进程,一个进程就对应了一个JVM实例,一个JVM实例中就有一个运行时数据区,一个运行时数据区只有一个Java堆、一个方法区,这个进程下的多个进程共享这个Java堆、方法区,每个线程各自拥有一套PC寄存器、虚拟机栈、本地方法栈。

1、程序计数器(也叫PC寄存器)

面试常问问题:

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

 (2):PC寄存器为什么会被设定为线程私有?

2、Java虚拟机栈

栈是运行时单位,堆是存储的单位。即:栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。堆解决的是数据存储的问题,即数据怎么放、放在哪里。

每个线程创建的时候都会创建一个Java虚拟机栈,是线程私有的,所以生命周期跟线程是一致的。其内部保存的是一个个的栈帧,一个栈帧就对应一个Java方法,栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息。不同线程中所包含的栈帧是不允许相互引用的。Java虚拟机主管程序的运行,它保存方法的局部变量(八种数据类型、对象的引用地址)、部分结果,并参与方法的调用和返回。

对于栈来说不存在GC问题,但是会有OOM。

2.1虚拟机栈中常见异常和栈大小的设置方法

 

 

 2.2栈帧的内部结构

 局部变量表(本地变量表)

定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用以及returnAddree类型。局部变量表最基本的存储单元是slot。在局部变量表里,32位以内的类型只占用一个slot(包括returnAddress),64位的类型(long和double)占两个slot。

2.2Java虚拟机栈的五到面试题

 1、固定的栈空间大小,可以通过设置-Xss设置栈的大小,空间不足:StackOverflowError;动态的栈空间:OOM,当不断地加栈帧,就会导致整个内存都不足,报错OOM。

2、不能保证。理论上只能让StackOverflowError出现晚一点。

3、不是越大越好。会挤占其他内存空间变小了

4、GC不会涉及虚拟机栈

5、何为线程安全?如果只有一个线程才可以操作此数据,则必是线程安全;如果有多个线程操作此数据则此数据是共享数据。如果不考虑同步机制,会存在线程安全问题。

具体问题具体分析:stringbuilder这个类本身是没有加上同步的,所以是线程不安全的(stringbuffer加了同步锁所以本身就是线程安全的)

例子1:这个时候s1的声明方式是线程安全的,因为只有一个线程会去操作此数据

 例子2:sBuilder的操作过程:线程不安全:主线程去操作了s,新建了一个线程也去并发操作了s,而sBuilder本身没有线程同步机制,就不安全了

 例子3:s1的操作:线程不安全的:因为返回值是s1,一返回出去就有可能被其他线程所调用

  

 例子4:s1的操作是线程安全的:s1在内部生的在内部死了,在内部消亡了,类似于例子1

3、Java堆 

在虚拟机栈中放的是对象的引用地址,对象实例是放在Java堆中

 

 

  

 如果对象在Eden区,出生经过一次minorgc后仍然存活,并且被survivor容纳的话,将会被移动到survivor区中,并将对象年龄设为1.对现在survivor区中梅奥过一次minorgc,年龄就增加一岁,当他的年龄增加到一定程度(默认为15),就会晋升到老年代中

 3.1TLAB

 

 

 

 

 

 3.2堆空间参数的设置

 

 

 3.3堆是分配对象存储的唯一选择吗?

    

 判断是否发生逃逸:看new对象实体是否会在方法外被引用

 

 4、方法区

4.1栈、堆、方法区交互关系

 

 堆存放的是new的对象,方法区有一部分放的是类的信息(.class)

 方法区放的是什么数据?放的是类型信息。

 

 

 

 

 5、运行时常量池

class文件中的常量池:

 

 运行时常量池:字节码文件中的常量池经过类加载器加载放到了方法区后,就是运行时常量池

 6、运行时数据区常见面试题

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值