1.Java运行时内存区域

Java运行时内存区域

JVM虚拟机运行时数据区域包括程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区。此外,java程序运行时也会经常用到本地内存。关于它们的内存分布图如下所示:
在这里插入图片描述
在这里插入图片描述

下面具体介绍下上面提到的几块内存区域:

程序计数器

一块较小的内存空间,它是当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变该计数器的值来选择下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都要依赖它来实现。

如果线程在执行一个Java方法时,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果在执行的是Native方法时,这个计数器的值为空。

Java虚拟机栈

虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法返回地址和一些额外的附加信息。

在编译程序代码时,栈帧中需要多大的局部变量表、多深的操作数栈都已经完全确定了,并且写入了方法表的Code属性之中。

本地方法栈

本地方法栈与虚拟机栈所发挥的作用非常相似,只是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为使用到的Native方法服务。

Java堆

Java堆是Java虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域,在虚拟机启动时创建。所有的对象实例以及数组都要在堆上分配内存。Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。
从内存回收角度看可以细分为:新生代和老年代;从内存私有与共享的使用角度看java堆可能划分出多个线程私有的分配缓冲区。

方法区(元空间)

方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

Hotspot在jdk1.6之前使用永久带来实现方法区。JDK1.7中,存储在永久代的部分数据被转移到了Java Heap或者是 Native Memory(Native Heap)。但永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了Native Memory;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap。
jdk8使用了元空间来实现方法区。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用Native Memory。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:

-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。

运行时常量池

该区域用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。运行时常量池相对于Class文件常量池的另一个重要特征是具备动态性,Java语言并不要求常量一定只能在编译期产生,也就是并非预置入Class文件中的常量池的内容才能进入方法区的运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的是String类的intern()方法。
在JDK1.8中,符号引用(Symbols)转移到了Native Memory;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap。

本地内存Native Memory(Native Heap)

本地内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,它直接从操作系统中分配,是java进程地址空间,因此不受Java堆大小的限制,但是会受到本机总内存的大小及处理器寻址空间的限制,因此它也可能导致OutOfMemoryError异常出现。

在JDK1.4中新引入了NIO机制,它是一种基于通道与缓冲区的新I/O方式,可以使用Native函数直接分配对外内,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中提高性能,避免了在Java堆和Native堆中来回复制数据。这种情况下的本地内存称之为Directory Memory。另外,DirectByteBuffer的引用对象是直接分配在堆得Old区的,因此其回收时机是在FullGC时。因此,需要避免频繁的分配DirectByteBuffer,这样很容易导致Native Memory溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值