java运行时数据区域

java运行时数据区域
分为线程私有的: 程序计数器、虚拟机栈、本地方法栈;
和各线程共享的: 堆、方法区。

程序计数器一块较小的内存空间,作用是指示当前线程所执行的字节码的行号。
字节码解释器通过程序计数器的值来选取下一条需要执行的字节码指令。
分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
如果虚拟机正在执行的是Native方法,这个计数器的值为空(Undefined)。
这块内存区域不会发生内存溢出。

java虚拟机栈
描述java方法执行的内存模型,每个方法被执行时,都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。
一个方法被调用至执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。
会发生StackOverflowError和OutOfMemoryError.

本地方法栈
与虚拟机栈作用相似,为虚拟机执行native方法时服务。


java堆
各线程共享,虚拟机启动时创建,唯一目的是存放对象实例。由垃圾收集器(GC)管理。
从不同角度,还可以细分为多种不同的空间,如新生代、老年代、Eden空间、From Survivor空间、To Survivor空间。
通常的虚拟机实现,java堆都是可扩展的,通过-Xmx和-Xms控制.

方法区
各线程共享,用于存储已被虚拟机加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据。
通过-XX:PermSize、-XX:MaxPermSize参数设置

运行时常量池
方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用。
这部分内容在类加载后存放到方法区的运行时常量中。

直接内存区
它不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,但是这部分内存也被频繁使用.
会导致OutOfMemoryError.
JDK1.4加入NIO(New Input/Output)类,引入了一种基于通道(channel)与缓冲区(buffer)的I/O方式,
它可以使用Native函数库直接分配堆外内存。然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。
这在一些场景中显著提高性能,因为它避免了在Java堆和Native堆中来回复制数据。
它的大小不受java堆大小的限制,但是会受到本机总内存及处理器寻址空间的限制。
可以通过-XX:MaxDirectMemorySize参数设置。如果不指定,则与java堆的最大值一样.

posted @ 2019-09-23 17:25  LinuSiyu  阅读(126)  评论(0编辑  收藏  举报