JVM内存模型深度剖析与优化

JVM运行时数据区结构

程序计数器

解释: 程序计数器就是记录当前线程锁执行的字节码的指示器,简单的说就是记录这个线程当前运行到哪个位置了。如果程序是单线程的,则程序计数器并没有实际意义,代码会一致顺序沿着指令执行下去,但是jvm支持多线程的,当某一个线程执行一般被挂起再次获取到时间片重新执行的时候必须知道它上次执行的位置,因此程序计数器是具备线程隔离性的,每个线程都有自己的程序计数器。

栈(线程栈)

解释:线程随着线程的创建而创建,随着线程的销毁而销毁,线程中的每个方法都会在栈内存中创建各自的栈帧,每个栈帧中有自己的局部变量、操作数栈、动态链接、方法出口等信息,每个方法从调用到执行完毕,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

  1. 局部变量:用来存放方法参数和方法内部定义的局部变量。
  2. 操作数栈:操作数栈是一个后入先出的栈,方法的执行操作都在操作操作数栈中完成,每一个字节码想操作数栈中写入和写出,就是操作数栈的入栈和出栈。
  3. 动态链接:每个栈帧都有一个指向运行时常量池,(JVM运行时的数据区域)中该栈所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。在Class文件格式的常量池中存有大量的符号引用(1、类的全限定名,2、字段名和属性,3、方法名和属性),字节码中的方法调用指令就是以常量池中指向方法的符号引用为参数。
  4. 方法出口:只有两种方法可以退出正在执行的方法,一个是执行引擎遇到方法返回字节码指令(return),这个时候会有返回值返回给方法的调用者,这种退出方法称为正常完成出口(Normal Method Invocation Completion)。另一种退出方式是方法遇到了异常并且在此方法体重没有得到处理,无论是JVM虚拟机自己产生的异常或者是试用throw字节码指令产生的异常,只要是在本方法中没有得到处理的异常,在本方法的异常处理器表中没有搜索到匹配的异常处理器,这种导致方法退出的方式称为异常完成出口(Abrupt Method Invocation Completion),这种方式的退出不会给方法的调用者任何返回值。

堆是随着java虚拟机产生的时候产生,生命周期是个虚拟机一样,并且是所有线程共享,里面的对象是有垃圾回收器回收,对象永远不会显式的释放,堆的大小可以是固定的也可以是动态的扩展,甚至还可以进行缩小,堆的内存的存放也不是连续的内存。超过堆的内存大小,jvm会报OutOfMemoryError,堆中存放的对象本身而不是对象的引用。

方法区

方法区在逻辑上是堆的一部分,但是方法区默认的是不进行垃圾回收或压缩,所有的方法区有个别名(non-heap),这里存放的是一些静态变量、类元信息(每个类的名称、方法信息、字段信息)、常量以及编译后的代码。

运行常量池

其实是方法区的一部分
方法区中有个运行时常量池:是每一个类或接口的常量池的运行时表现形式,在类和接口被加载到JVM中后,对应的常量池就被创建出来,在运行期间也可以将新的常量放入常量池中。

本地方法栈

和java虚拟机栈的作用差不多,只不过是为JVM使用到的native方法进行服务的。(methods written in a language other than the Java programming language),和java虚拟机栈一样,可以固定大小也可以动态扩展或收缩,使用的时候内存不够会报StackOverflowError,扩展的时候可用内存不够会报OutOfMemoryError。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值