JVM体系结构之一:总体介绍
一、Java的内存区域划分
Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域。
Java的内存区域主要分为五部分:
- 程序计数器(PC)
- Java 虚拟机栈(JVM Stack)
- 本地方法栈(Native Method Stack)
- Java 堆内存(Java Heap)
- 方法区(Method Area)
1.1、按照功能
1.2、按照内存是否共享
- 类装载器(ClassLoader)(用来装载.class文件)
- 执行引擎(执行字节码,或者执行本地方法)
- 运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈),如下图:
下面我们来解析这几个区域。
1、程序计数器
程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的信号指示器。每一条JVM线程都有自己的PC寄存器在任意时刻,一条JVM线程只会执行一个方法的代码。该方法称为该线程的当前方法(Current Method)如果该方法是java方法,那PC寄存器保存JVM正在执行的字节码指令的地址,如果该方法是native,那PC寄存器的值是undefined。
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
2、Java 虚拟机栈
Java虚拟机栈也是线程私有的,每一条线程都拥有自己私有的Java虚拟机栈,它与线程同时创建。并且生命周期与线程相同。它描述了Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至完成的过程,都对应一个栈帧从入栈到出栈的过程。关于栈帧详细的内容在后边复习虚拟机字节码执行引擎的时候再说吧。
Java 虚拟机栈在方法调用和返回中也扮演了很重要的角色。因为除了栈帧的入栈和出栈之外,Java虚拟机栈不会再受其它因素的影响,因此栈帧可在系统的堆上分配内存(注意,是系统的Heap而不是Java Heap)。Java虚拟机栈所使用的内存不需要保证是连续的。
3、本地方法栈
Java可以通过java本地接口JNI(Java Native Interface)来调用其它语言编写(如C)的程序,在Java里面用native修饰符来描述一个方法是本地方法。本地方法栈就是虚拟机线程调用Native方法执行时的栈,它与虚拟机栈发挥类似的作用。但是要注意,虚拟机规范中没有对本地方法栈作强制规定,虚拟机可以自由实现,所以可以不是字节码。如果是以字节码实现的话,虚拟机栈本地方法栈就可以合二为一,事实上,OpenJDK和SunJDK所自带的HotSpot虚拟机就是直接将虚拟机栈和本地方法栈合二为一的。
Java虚拟机规范规定该区域也可抛出StackOverFlowError和OutOfMemoryError。
4、Java 堆
这个区域用来放置所有对象实例以及数组。不过在JIT(Just-in-time)情况下有些时候也有可能在栈上分配对象实例。堆也是java垃圾收集器管理的主要区域(所以很多时候会称它为GC堆)。
从GC回收的角度看,由于现在GC基本都是采用的分代收集算法,所以堆内存结构还可以分块成:新生代和老年代;再细一点的有Eden空间、From Survivor空间、To Survivor空间等。如下图:
5、方法区
方法区是可供各条线程共享的运行时内存区域。存储了每一个类的结构信息,例如运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法
方法区创建时机:在虚拟机启动的时候创建。
方法区的容量:可以是固定大小的,也可以随着程序执行的需求动态扩展,并在不需要过多空间时自动收缩。方法区在实际内存空间中可以是不连续的。
6、直接内存
直接内存(Direct Memory)虽然不是程序运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但这部分内存也被频繁使用,而且它也可能导致OutOfMemoryError异常出现。
在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native方法库直接分配堆外内存,然后通过一个存储在Java堆里面的DirecByteBuffer对象作为这块内存的引用进行操作。这样能在某些应用场景中显著提高性能,因为它避免了在Java堆和Native堆中来回复制数据。
显然,本机直接内存的分配不会受到Java堆大小的限制,但是,还是会受到本机总内存(包括RAM及SWAP区或者分页文件)的大小及处理器寻址空间的限制,从而导致动态扩展时出现OutOfMemoryError异常。
7、执行引擎
将字节码即时编译 优化 为本地代码, 然后执行。
在了解完这些知识以后,就可以知道:类和对象在运行时的内存里是怎么样的?以及各类型变量、方法在运行时是怎么交互的?
在程序运行时类是在方法区,实例对象本身在堆里面。
方法字节码在方法区。线程调用方法执行时创建栈帧并压栈,方法的参数和局部变量在栈帧的局部变量表。
对象的实例变量和对象一起在堆里,所以各个线程都可以共享访问对象的实例变量。
静态变量在方法区,所有对象共享。字符串常量等常量在运行时常量池。
各线程调用的方法,通过堆内的对象,方法区的静态数据,可以共享交互信息。
各线程调用的方法所有参数传递、方法返回值的返回,都是使用栈帧里的操作数栈来完成的。
JVM体系结构之一:总体介绍的更多相关文章
- TMS320C54x系列DSP的CPU与外设——第2章 TMS320C54x DSP体系结构总体介绍
第2章 TMS320C54x DSP体系结构总体介绍 本章介绍TMS320C54x DSP体系结构的概况,包括中央处理单元(CPU).存在器和片内外设. C54x DSP采用了高级的改进哈佛结构,用8 ...
- JVM内存结构之一--总体介绍
Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域. 有的人把JVM管理的内存简单地分为堆内存和栈内存,这样分未免有些太肤浅了. Java ...
- JVM 内部运行线程介绍
转(http://club.alibabatech.org/article_detail.htm?articleId=4) JVM 内部运行线程介绍 作者:蒋家佳/觉梦(支付宝开发工程师) 浏览量: ...
- JVM 体系结构概述 (一)
一.jvm运行在操作系统之上的,它与硬件没有直接交互: 二.JVM体系结构概览 JVM的基本结构:类加载器.执行引擎.运行时数据区.本地方法接口: 过程:class文件 ----> 类加载器 - ...
- [转帖]Kubernetes及容器编排的总体介绍【译】
Kubernetes及容器编排的总体介绍[译] 翻译自The New Stack<Kubernetes 生态环境>作者:JANAKIRAM MSV和 KRISHNAN SUBRAMANIA ...
- JVM体系结构之三:方法区之2(jdk1.6,jdk1.7,jdk1.8下的方法区变迁)
方法区 方法区存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.HotSpot中也称为永久代(Permanent Generation),(存储的是除了Java应用程序创建的对象之 ...
- JVM体系结构之三:方法区之1
一.简介 方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域.在方法区中,存储了每个类的信息(包括类的名称.方法信息.字段信息).静态变量.常量以及编译器编译后的代码等. 方法区( ...
- JVM 体系结构与工作方式
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- java虚拟机之JVM体系结构
JVM体系结构: 下面重点介绍运行时数据区域模块: (1)java堆(Heap) 被所有线程共享的一块内存区域,在虚拟机启动时创建 用来存储对象实例 可以通过-Xmx和-Xms控制堆的大小 OutOf ...
随机推荐
- spring 事物管理
示例:模拟实现转账操作,"A"转给"B"1000,"A"少1000而"B"多一千. 一.转账环境搭建 1.xml配置文件 ...
- Mac idea maven 创建web项目
这样项目就创建完成了.然后把Tomcat加入进去就可以跑通了.
- eclipse 安装 json Editor Plugin的方法
json Editor Plugin是一款可以显示JSON高亮语法,折叠的eclipse插件.但目前网上的安装方法少,且几乎都无效.我按照官网的步骤安装很容易就成功了,现在贴出步骤供大家参考: 1.在 ...
- SAP basis 常用事物
1.创建一个新的用户 完成client创建和拷贝后,在开始正式工作之前,需要创建新的用户. 用这个用户进行工作.默认ddic和sap*用户不要用于实际的业务. 创建用户的过程很简单,只要以su01 ...
- SpringBoot学习笔记(7):Druid使用心得
SpringBoot学习笔记(7):Druid使用心得 快速开始 添加依赖 <dependency> <groupId>com.alibaba</groupId> ...
- 自定义xhr请求
接上一篇博客,上一篇是之前的jsonp请求方法的封装,这一篇是xhr请求的简单封装. 原理: 1:new一个xhr对象,命名为ajaxRequest,由于浏览器兼容性的问题,所以将获取xhr对象的方式 ...
- 模仿jquery框架源码
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- 牛客小白月赛1 A 简单题 【数学】
题目链接 https://www.nowcoder.com/acm/contest/85/A 思路 这个 就是 E 但是 运算的时候 要保证 其精度 AC代码 #include <cstdio& ...
- RTMP & HLS
一,直播云架构 2. RTMP 协议 RTMP(Real Time Messaging Protocol)是Adobe Systems公司为Flash播放器和服务器之间音频.视频和数据传输开发的开放协 ...
- linux开机过程
一.MBR(main boot record)主引导记录 主引导记录位于0盘面,0磁道,0扇区,早期由512个字节组成. 其中446个字节是boot loader程序.Boot Loader是在操作系 ...