JVM数据区

jvm运行时数据区

程序计数器

当前线程所执行的字节码的行号指示器,如果是java方法,值为正在执行的虚拟机字节码指令的地址;如果是本地方法(由其他语言例如c实现,一般用来访问操作系统),值为空。

程序计数器是线程私有的

虚拟机栈

每个方法被执行的时候,java虚拟机都会同步创建一个栈帧用来存储局部变量表、操作数栈、动态连接、方法出口等信息。方法调用栈帧进入虚拟机栈,方法结束出栈。

局部变量表:存放了基本数据类型(int、boolean、byte、char等等)、对象引用和returnAddress(指向了一条字节码指令的地址)。

两类异常:

  1. 如果线程请求的栈超过虚拟机允许的范围,就抛出StackOverflowError异常。
  2. 如果栈可以动态扩容,就会抛出OutOfMemoryError异常。

本地方法栈

与虚拟机栈类似,区别是虚拟机栈执行的是java方法,本地方法栈执行本地方法。

唯一目的是存放对象实例,几乎所有对象实例都在这分配内存。

java堆可以处于物理上不连续的内存空间上,但逻辑上是连续的。

如果堆中已经没有内存可以分配了,并且堆无法再扩展,jvm会抛出OutOfMemoryError异常。

方法区

用于存储被虚拟机加载了的类信息,常量,静态变量和代码缓存,方法区中堆中,为了区分,它被称为”非堆“。

在jdk7及以前,使用永久代来实现方法区,在jdk8之后,使用元空间。

运行时常量池

运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量(例如字符串常量池中"java"这个值)和符号引用。

直接内存

  • 直接内存不是jvm定义的内存区域,即在jvm之外分配。
  • 直接内存的分配和回收由开发人员手动管理,需要显式地分配和释放内存,没有jvm的内存回收机制。
  • 直接内存的访问速度通常比堆内存快,因为它绕过了 JVM 的内存回收机制。

NIO可以使用Native函数库直接分配堆外内存,然后通过一个存储在堆里面的DirectByteBuffer对象作为这块内存的引用解析操作,可以通过避免在java堆和native堆(jvm外部)中反复复制数据来提高性能。

直接内存 vs 堆内存

直接内存创建和销毁的代价昂贵,但读写性能高(少一次内存复制),适合配合池化功能一起用

直接内存对 GC 压力小,因为这部分内存不受 JVM 垃圾回收

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值