jvm内存区域

一.程序计数器

程序计数器其实就是一个程序所执行的字节码行号的指示器。通过这个指示器可以选取下一条要执行的字节码
为了线程上下文切换时可以恢复到以前的状态,所以每个线程都有一个私有的程序计数器,使得各个线程之间互不影响。
如果执行的是java方法就则计数器存储的是正在执行的字节码指令地址,如果是native方法则为空,因此程序计数器是唯一一块不会发生OOM的内存区域。

二.虚拟机栈

虚拟机栈也是线程私有的,所以有一种线程安全的策略就是利用栈隔离。
虚拟机栈用于存储局部变量表,操作数栈,动态链接和方法出口等信息。
一般程序员关注的是就是局部变量表。它存储的是各种基本数据类型,对象的引用(一种是对象的地址,一种是包含对象信息的句柄地址) 以及returnAddress类型。
如果申请的栈深度达到了虚拟机所允许的最大深度,那么会抛出stackOverflowError。比如无递归出口的递归函数。如果线程所申请的内存到达的虚拟机的最大内存会抛出OutOfMemoryError

三.本地方法栈

本地方法栈其实就是native函数库所使用的栈,本质和虚拟机栈一样。区别是虚拟机栈运行的是java方法,本地方法栈使用的语言跟寻实现虚拟机所用的语言。
和虚拟机栈一样也会发生stackOverflowError和OutOfMemoryError

四.java堆

堆内存主要是用来存放对象实例的,所有线程共享。具体可分为新生代和老年代。每一个线程都有一个分配缓存区(Thread Local Allocation Buffer,TLAB),用来保证分配内存时的线程安全
当虚拟机无法为对象分配内存时会抛出OutOfMemoryError

五.方法区

方法区属于线程共享的区域,用来存储已被加载的类信息,常量,静态变量以及被编译后的代码。
HotSpot虚拟机上把方法区重新定义为”永久代“,把GC的范围扩充至方法区,但是不好用,jdk1.7中已经把常量池从永久代中移出
同样方法区也会抛出OutOfMemoryError

六.运行时常量池

运行时常量池是方法区的一部分,每个class文件除了一些类版本,字段,方法,接口等描述信息外,还有常量池,常量池用于存储各种字面量和符号引用。当把class文件加载到方法区时会把class文件的常量池加载到运行时常量池中。
String.intern()方法就是把指定字符丢到常量池中。
运行时常量池属于方法区也会抛出OutOfMemoryError

七.直接内存

直接内存不属于java内存区域,属于堆外内存。
jdk1.4引入的NIO就是可以直接操作native函数库直接操作堆外内存,java堆中的DirectorByteBuffer对象直接引用了这块内存,避免了native堆到java堆的复制,有效的提高了IO的效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值