JVM学习笔记之运行时数据区

本文详细介绍了Java虚拟机(JVM)运行时数据区的主要组成部分,包括程序计数器(PC寄存器)、虚拟机栈、本地方法栈、堆和方法区。深入探讨了这些部分的功能、特点及其在内存管理中的作用。

运行时数据区整体架构

一、PC寄存器(程序计数器)

1.介绍(内部既没有GC,也没有OOM)

2.作用

3.举例

4.PC寄存器常见问题

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

答:因为在一个进程中,CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。JVM字节码解释器就需要通过改变PC寄存器的值来明确下一跳该执行什么样的字节码指令。

2.PC寄存器为什么会被设定为线程私有的?

答:为了能够准确的记录各个线程正在执行的当前字节码指令地址。

二、虚拟机栈

1.优缺点

优点:跨平台、指令集小、编译器容易实现

缺点:性能下降、实现相同功能所需的指令更多

2、栈与堆的区别

栈是运行时的单位,而堆是存储的单位。

即:栈解决程序运行问题,即程序如何执行,或者说如何处理数据。

      堆解决的时数据存储问题,即数据放哪里,怎么放。

3.概述

4.特点

5.栈中可能出现的异常

1.StackOverflowError

2.OutOfMemoryError

我们可以使用:-Xss 来设置线程的最多栈空间。

/**
 * 演示栈中的异常:StackOverflowError
 *
 *  默认情况下:count = 11415
 *  设置栈的大小:-Xss256k  : count = 2458
 */
public class StackErrorTest {
    private static int count = 1;
    public static void main(String[] args) {
        System.out.println(count);
        count++;
        main(args);
    }
}

6.栈帧的内部结构

每个栈帧中存储着:

  局部变量表(所需容量的大小在编译器就确定下来)

         定义为一个数字数组,主要用户存储方法参数和定义在方法体内的局部变量。

         最基本的存储单元时Slot(变量槽),32bit以内占用一个槽,64bit类型占用两个槽。byte、short、char在存储前被转换为int,boolean也会转换为0表false、1表true。

         非静态方法的局部变量表index=0的Solt位置放的this

         slot时可以重复利用的,如果一个局部变量过了作用域,那么其作用域只会申明的变量就很可能复用过期局部变量的槽位。

  操作数栈(或表达式栈)

            栈顶缓存技术:

  动态链接(或执行运行时常量池的方法引用)

              链接与方法绑定机制

              非虚方法

                  静态方法、私有方法、final方法、构造方法、父类方法都是非虚方法。

              方法调用指令

             虚方法表

  方法返回地址(或方法正常return退出或者异常退出的定义)

         

         

  一些附加信息

  方法中定义的局部变量是否是线程安全的?(具体问题分析)

     答:线程安全的:方法中的局部变量是内部定义,且在内部就消亡的为;

       线程不安全的:方法中有参数传入,或有返回值返回。

三、本地方法栈

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

        是线程私有的;允许被实现成固定或者是可动态扩展的内存大小。

        本地方法使用c语言实现的;具体做法是本地方法栈登记本地方法,在执行引擎执行时加载本地方法库。

本地方法接口与本地方法库(非运行时数据区的结构)

1.何为本地方法(native不能与abstract一同存在修饰方法)

         一个本地方法就是一个java调用非java代码的接口。

         作用:融合不同编程语言为java所用。

2.为什么要使用native method

四、堆(heap)

1.堆的概述

          堆中存在TLAB区:每个线程独有一份(提高并发量)

2.默认堆空间的大小

3.年轻代与老年代(大小比例为1:2)

  Eden:s0:s1 = 8:1:1;

  几乎所有对象都是在Eden区被new出来的;绝大部分对象都是在新生代销毁的。

4.对象分配(只有伊甸园区满才会触发YGC/Minor GC)

      

      

      

      

      详细图解(包括特殊情况)

            

5.三种GC的对比

       

       

        

        

6.堆空间的分代思想(为了优化GC性能)

         

7.内存分配策略

         

8.对象分配过程:TLAB

         

         

         

          

9.堆空间中常用参数

          

          

          -XX:HandlePromotionFailure在JDK7后默认为true;只要老年代的连续空间大于新生代对象总大小或者历次晋升平均大小就会进行Minor GC,否则进行Full GC。

10.逃逸分析(没有逃逸的对象可以栈上分配)

          

           

          

     代码优化

           

         标量替换或分离对象:就是将未逃逸的对象拆分为标量,这样内存就是分配在栈上了。

           

五、方法区

1.栈、堆、方法区的交互关系

    

2.方法区的基本理解

     

    

3.方法区的演变

      在jdk7及以前,习惯上把方法区,称为永久代。jdk8开始,元空间取代了永久代(不等价)。

元空间与永久代的区别:

      元空间使用的是本地内存空间,并非jvm中的内存空间。

      永久代使用的是jvm中的内存空间(容易OOM)。

       

       

永久代为什么被元空间替换?

       

4.设置方法区内存大小

     

     

5.方法区的内部结构

      

方法区存储什么?

     

     

常量池

     为什么需要常量池?

      

      

运行时常量池

      

6.方法区的垃圾回收

      

      

      

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值