java内存结构

https://www.cnblogs.com/ysocean/p/9345787.html

虚拟机

  • 语言无关,只要语言能够编译成class文件,都能够在java虚拟机上运行
  • 平台无关,不同的系统实现不同的Java虚拟机。Java虚拟机就相当于操作系统和应用程序之间的中介,每种平台安装适应该平台的Java虚拟机,那么我们编写的程序当然能够在任意平台运行
  1. 编译: Person.java -> 词法分析器 -> tokens流 -> 语法分析器 -> 语法树/抽象语法树 -> 语义分析器-> 注解抽象语法树 -> 字节码生成器 -> Person.class文件,

    Java编译一个类时,如果这个类依赖的类还没有被编译,会首先编译这个被依赖的类,然后引用,如果java编译器在指定目录下找不到该类所依赖的的.class文件,或.java文件,编译器会报错cant find symbol

    notebook++ 二进制插件可查看class文件。Class文件是一组以8位字节为基础单位的二进制流。每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Calss文件。也就是 CA FE BA BE 这四个字节。类似于身份标识。

    0000 0034 对应10进制的52,代表JDK 8中的一个版本。

    0027 对应十进制27,代表常量池中27个常量。

  2. 加载

    1. 通过类的全限定名获取定义此类的二进制字节流
    2. 将字节流所代表的静态存储结构转化为方法区的运行时数据结构
    3. 在java堆中生成一个代表整个类的java.lang.Class对象,作为堆方法区的访问入口。

    JVM类加载器作用:把class文件字节码内容 加载到内存中。并将这些静态数据转换成方法区运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区数据的访问入口 。类加载器通过ClassLoader及其子类完成。

    在加载完毕到执行过程中,JVM会将程序执行时用到的数据和相关信息存储在运行时数据区(Runtime Data Area),这块区域也就是我们常说的JVM内存结构,垃圾回收也是作用在该区域。

    img

1. 运行时数据结构区 Runtime Data Area

img

img

2.程序计数器 Program Conputer Register

较小的内存空间,当前线程所执行的字节码的行号指示器。字节码解释器的工作就是改变计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程回复等基础功能都依赖整个计数器完成。

  1. 线程私有,

    java虚拟机支持多线程,通过线程轮流切换并分配处理器执行时间的方式来实现,任一确定的时刻,一个处理器只会执行一条线程中的指令,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器。

  2. 记录当前字节码执行地址。

    当前线程执行的java方法,计数器记录的是正在执行的虚拟机字节码指令地址,如果是Native方法,计数器值为1

  3. 不抛OutOfMemoryError异常。

3. 虚拟机栈

Java虚拟机栈(Java Virtual Machine stack),这块区域也是线程私有的,与线程同时创建,用于存储栈帧。Java 每个方法执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息,每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

img

  • 线程私有,虚拟机栈生命周期与线程保持一致。
  • 每个方法执行都会创建一个栈帧用于存储,局部变量表,操作栈,动态链接,方法出口等信息,每个方法被调用直至执行完成的过程,都对应一个栈帧在虚拟机栈中从入栈到出栈的过程。
  • 抛出StackOverflowError 和 OutOfMemoryError 异常 ,如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflow Error异常,如果虚拟机栈可以动态扩展,当扩展时无法申请到足够内存时会抛出OutOfMemory异常。

4 本地方法栈

本地方法栈(Native Method Stacks)作用和虚拟机栈类型,虚拟机栈执行的是Java方法,本地方法栈执行的是 Native 方法,本地方法栈也会抛出抛出 StackOverflowError 和 OutOfMemoryError 异常。

注意:由于虚拟机规范并没有对本地方法栈中的方法使用语言、使用方式和数据结构强制规定,因此具体的虚拟机可以自由实现它。上图我们也给出在 HotSpot 虚拟机中,本地方法栈和虚拟机栈合为一体了

5 Java堆

是Java虚拟机管理内存最大,所有线程共享的一块区域。目的是用来存放对象,基本上所有的对象实例和数组都在堆上分配(不是绝对)。Java堆也是垃圾回收器管理的主要区域。

  1. 线程共享,否则多线程工作占用内存很大,线程共享设计会带来多线程并发资源冲突问题。
  2. 存放对象,数组。(随着jit编译器的发展和逃逸分析技术的成熟,栈上分配、标量替换等优化技术会导致对象不一定在堆上进行分配)
  3. 垃圾回收。
  4. 会抛出OutOfMemory异常.Java堆可以处于物理上不连续的内存空间中,逻辑上连续即可,实现时既可以实现成固定大小,也可以扩展,如果堆中没有完成实例分配,堆也无法扩展,将抛出OutOfMemoryError异常。

6. 方法区

  • Method Area,用来存放已被虚拟机加载的类结构信息,常量,静态变量,即时编译器编译后的代码等数据。
  • 方法区也称为“永久代”,这是因为垃圾回收器对方法区的垃圾回收比较少,主要是针对常量池的回收以及对类型的卸载,回收条件比较苛刻。经常会导致对此内存未完全回收而导致内存泄露,最后当方法区无法满足内存分配时,将抛出 OutOfMemoryError 异常 ,
  • 在JDK1.8 的 HotSpot 虚拟机中,已经去掉了方法区的概念,用 Metaspace 代替,并且将其移到了本地内存来规划了

7 运行时常量池 Runtime Constant Pool

用于存放编译期生成的各种字面量和符号引用,是方法区的一部分。但是Java虚拟机规范对其没有做任何细节的要求,所以不同虚拟机实现商可以按照自己的需求来实现该区域,比如在 HotSpot 虚拟机实现中,就将运行时常量池移到了堆中。

  • 存放字面量、符号引用、直接引用

    通常来说,该区域除了保存Class文件中描述的引用外,还会把翻译出来的直接引用也存储在运行时常量池,并且Java语言并不要求常量一定只能在编译器产生,运行期间也可能将常量放入池中,比如String类的intern()方法,当调用intern方法时,如果池中已经包含一个与该String确定的字符串相同equals(Object)的字符串,则返回该字符串。否则,将此String对象添加到池中,并返回此对象的引用

    String s1 = "AB";
    String s2 = new String("AB");
    String s3 = "A";
    String s4 = "B";
    String s5 = "A" + "B";
    String s6 = s3 + s4;
    System.out.println(s1 == s2);//false
    System.out.println(s1 == s5);//true
    System.out.println(s1 == s6);//false
    System.out.println(s1 == s6.intern());//true
    System.out.println(s2 == s2.intern());//fasle
    

    这里写图片描述

    https://blog.csdn.net/ifwinds/article/details/80849184

  • 抛出 OutOfMemoryError 异常

    运行时常量池是方法区的一部分,会受到方法区内存的限制,当常量池无法申请到内存时,会抛出该异常。

8 直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,它也不是Java虚拟机规范定义的内存区域。我们可以看到在 HotSpot 中,就将方法区移除了,用元数据区来代替,并且将元数据区从虚拟机运行时数据区移除了,转到了本地内存中,也就是说这块区域是受本机物理内存的限制,当申请的内存超过了本机物理内存,才会抛出 OutOfMemoryError 异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值