java内存结构(执行时数据区域)
java虚拟机规范规定的java虚拟机内存事实上就是java虚拟机执行时数据区,其架构例如以下:
当中方法区和堆是由全部线程共享的数据区。
Java虚拟机栈。本地方法栈和程序计数器是线程隔离的数据区。
(1).程序计数器:
是一块较小的内存空间,其作用能够看作是当前线程所运行的字节码的行号指示器,字节码解析器工作时通过改变程序计数器的值来选取下一条须要运行的字节码指令。
程序的分支、循环、跳转、异常处理以及线程恢复等基础功能都是依赖程序计数器来完毕。
Java虚拟机的多线程是通过线程轮流切换并分配处理器运行时间片来实现。在不论什么一个时刻,一个处理器仅仅会运行一条线程指令。因此。为了确保线程切换之后能恢复到正确的运行位置,每条线程都须要一个独立的程序计数器,因此程序计数器是线程私有的内存。
程序计数器是java虚拟机中唯一一个没有规定不论什么内存溢出OutOfMemoryError的内存区域。
(2).java虚拟机栈:
Java虚拟机栈也是线程私有的。它的生命周期与线程同样。
虚拟机栈描写叙述的是java方法运行的内存模型:每一个方法被运行时都会同一时候创建一个栈帧用于存放局部变量表、操作数栈、动态连接和方法出口等信息。每一个方法被调用直至运行完毕过程,就相应着一个栈帧在虚拟机中从入栈到出栈的过程。
Java虚拟机栈的局部变量表存放了编译器可知的8种java基本类型数据、对象引用(注意不是对象实例本身)、方法返回地址returnAddress。
Java虚拟机栈的局部变量表空间单位是槽(Slot),当中64位长度的double和long类型会占用两个slot。其余的数据类型仅仅占用一个slot。
局部变量表所需内存空间在编译期间完毕分配,当进入一个方法时。该方法须要在帧中分配多大的局部变量空间是全然确定的,在方法执行期间不会改变局部变量表的大小。
Java虚拟机栈有两种异常状况:假设线程请求的栈深度大于虚拟机所同意的最大深度时,抛出StackOverflowError异常;假设虚拟机栈能够动态扩展,当扩展时无法申请到足够内存时会抛出OutOfMemoryError异常。
(3).本地方法栈:
本地方法栈与java虚拟机栈作用很类似。其差别是:java虚拟机栈是为虚拟机运行java方法服务。而本地方法栈是为虚拟机调用的操作系统本地方法服务。
Java虚拟机规范没有对本地方法栈的实现和数据结构做强制规定。Sun HotSpot虚拟机直接把java虚拟机栈和本地方法栈合二为一。
与java虚拟机栈类似,本地方法栈也会抛出StackOverflowError异常和OutOfMemoryError异常。
(4).堆:
堆是java虚拟机所管理的内存区域中最大一块,java堆是被全部线程所共享的一块内存区域。在java虚拟机启动时创建。堆内存的唯一目的就是存放对象实例。差点儿全部的对象实例都是在堆分配内存。
Java堆是垃圾收集器管理的主要区域。从垃圾回收的角度看,因为如今的垃圾收集器基本都採用的是分代收集算法。因此java堆还能够初步细分为新生代和年老代。
Java虚拟机规范规定,堆能够处于物理上不连续的内存空间中,仅仅要逻辑上是连续的就可以。在实现上即能够是固定大小的。也能够是可动态扩展的。假设在堆中没有内存完毕实例分配,而且堆大小也无法在扩展时,将会抛出OutOfMemoryError异常。
(5).方法区:
方法区与堆一样,是被各个线程共享的内存区域。它用于存储已被虚拟机载入的类信息、常量、静态变量、即时编译后的代码等数据。尽管java虚拟机规范把方法区描写叙述为堆的一个逻辑部分,可是方法区却有一个别名叫Non-Heap(非堆)。
Sun HotSpot虚拟机把方法区叫永久代(Permanent Generation),方法区中最重要的部分是执行时常量池。
Class文件里除了有类的版本号、字段、方法、接口等描写叙述信息外,另一项信息是常量池。用于存放编译期生成的各种字面变量、符号引用、直接引用等,这些内容将在类载入后存放到方法区的执行时常量池中,另外在执行期间也能够将新的常量存放到常量池中,如String的intern()方法。
方法区和执行时常量池在无法满足内存分配时,也会抛出OutOfMemoryError异常。
(6).直接内存:
直接内存并非java虚拟机执行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。可是在java开发中还是会使用到。
JDK1.4中新引入的NIO(new I/O),引入了一种基于通道(Channel)和缓冲区(Buffer)的I/O方式,能够使用操作系统本地方法库直接分配堆外内存,然后通过一个存储在java堆里面的DirectByteBuffer对象作为堆外直接内存的引用进行操作,避免了java堆内存和本地直接内存间的数据拷贝,能够显著提高性能。
尽管直接内存并不直接收到java虚拟机内存影响。可是假设java虚拟机各个内存区域总和大于物理内存限制,从而导致直接内存不足,动态扩展时也会抛出OutOfMemoryError异常。
java虚拟机内存结构中的程序计数器、虚拟机栈和本地方法栈这三个区域随线程创建而生,随线程销毁而灭,因此这三个区域的内存分配和回收是确定的。java垃圾收集器重点关注的是java虚拟机的堆内存和方法区内存。
java内存结构(执行时数据区域)的更多相关文章
- [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义
前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine ,既然是虚拟机, ...
- 想买保时捷的运维李先生学Java性能之 运行时数据区域
前言 不知道自己不知道,不知道自己知道,知道自己不知道,知道自己知道,目前处于知道自己不知道这个阶段,很痛苦啊,干了4年了运维,是一个坎.越来越发觉想要走得远,还是得扎根底. 一.运行时数据区域 ...
- 深入理解Java虚拟机-JVM运行时数据区域
一.运行时数据区域 1.程序计数器 程序计数器( Program Counter Register) 是一块较小的内存空间, 它可以看作是当前线程所执行的字节码的行号指示器. Java虚拟机的多线程是 ...
- JAVA虚拟机运行时内存划分--运行时数据区域
Java虚拟机在执行java程序时会把内存划分为以下几个不同的数据区域: java虚拟机内存划分(运行时)1.线程私有的: 程序计数器(Program Counter Register):可以看作当前 ...
- JVM内存结构——运行时数据区
在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program C ...
- 深入理解JVM:JVM执行时数据区域分类
JVM在运行java程序的过程中会把他所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途和创建.销毁时间.有些区域随着虚拟机的启动而存在.有些区域则依赖用户线程的启动和结束而建立和销毁. ...
- Java虚拟机(一)结构原理与运行时数据区域
我们来学习Java虚拟机的结构原理与运行时数据区域. 1.Java虚拟机概述 Oracle官方定义的Java技术体系主要包括以下几个部分: Java程序设计语言 各种平台的Java虚拟机 Class文 ...
- Java虚拟机 - 结构原理与运行时数据区域
http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关 ...
- Java内存区域(运行时数据区域)和内存模型(JMM)
Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...
随机推荐
- Find Minimum in Rotated Sorted Array 典型二分查找
https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array/ Suppose a sorted array is rot ...
- 洛谷P1894 [USACO4.2]完美的牛栏The Perfect Stall(二分图)
P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星 ...
- Spring Boot (5) Spring Boot配置详解
application.properties application.properties是spring boot默认的配置文件,spring boot默认会在以下两个路径搜索并加载这个文件 src\ ...
- Inception搭建
Inception安装Inception是集审核.执行.回滚于一体的一个自动化运维系统,它是根据MySQL代码修改过来的,用它可以很明确的,详细的,准确的审核MySQL的SQL语句,它的工作模式和My ...
- C#屏蔽Alt+F4,解决Alt+F4关闭窗体时对话框NO后,线程不退出问题
//1.将窗体的属性KeyPrieview设置为true //keypreview属性为true的时候,就可以响应键盘事件v //2.在窗体KeyDown事件中加如下代码 private void F ...
- js动态操作订单表格
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 安卓JNI使用C++类
安卓JNI使用C++类,同时可使用C++的类成员变量,这就必须保证程序持续保存Native状态,即长期维护C++对象的地址.完成初始化之后,需要使用对象成员的java层函数需要传入对象的地址. 一.N ...
- git解决内容冲突
内容冲突的冲突处理 两个用户修改了同一个文件的同一块区域,git会报告内容冲突. 解决办法:打开发生冲突的文件,会发现 <<<<<<< HEADtest in ...
- html formData 数据 提交和 .netMVC接收
<form id="uploadForm" enctype="multipart/form-data"> <input type=" ...
- C#使用OracleDataReader返回DataTable
string data = string.Empty; DataTable OutDataTable = new DataTable(); OracleDataReader daReader = cm ...