深入理解JVM虚拟机(一):JVM运行时数据区

概述:

JVM将内存的管理进行封装,使得开发人员不必关心内存申请、释放操作。但是在高级程序开发、复杂业务场景开发的时候,如果出现内存溢出的情况,对于开发人员而言就很难去分析出原因。所以还是很有必要去了解一下JVM是如何进行内存操作的。

基础知识普及

  • 堆(Heap):是一种数据结构,数据存储方式是先进先出(FIFO-first in first out),并且以树结构进行存储,顾名思义只允许首位操作,不允许操作中间数据。堆是计算机为开发人员分配的一个存储空间,由开发人员自由支配,开发人员如果不释放,则数据一直占据在内存中,当程序结束时,系统会进行回收。堆使用的是二级缓存
  • 栈(Stack):也是一种数据结构,数据结构存储方式是先进后出(FILO-first in last out),所以只允许在队列头进行操作,不允许中间、尾部操作。栈是操作系统使用的存储区域,使用的是一级缓存
  • 进程(Progress):进程是一个独立运行的程序,它可以申请、拥有系统资源。在Linux下可以通过ps命令查看系统进程信息,Windows下通过TaskList命令查看进程信息。计算机将进程作为最小的资源分配单位。进程与进程之间不存在数据共享,所以进程之间只能进行通讯。
  • 线程(Thread):线程是更小的执行单位,它不可以申请、拥有系统资源。线程的出现会使得CPU时间的利用率更高:当CPU为当前进程分配时间片的时候,当前进程会根据线程的情况再次分配。线程之间可以进行数据共享。通过此链接可以秒懂进程、线程的含义:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
  • 程序计数器(Program Counter):它是用来存储下条指令存储单元。当执行一条指令时,将指令由内存取到指令寄存器中,此过程称之为“取指令”,与此同时,PC中的地址或自动加1或由转移指针给出下一条指令。这个过程就是由程序计数器来换成。

JVM管理的内存结构

JVM管理的内存结构图

介绍

  • 程序计数器(Program Counter):是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器。由于JAVA虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都要有一个独立的程序计数器,各条线程之间的计数器互不影响,我们称这类区域为“线程私有”的内存。如果线程正在执行的是一个JAVA方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域
  • Java虚拟机栈(JVM Stacks):它也是线程私有的,他的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时会建立一个栈帧(Stack Frame,它是方法运行时的基础数据结构)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用开始到执行完成的过程,就对应有一个栈帧在虚拟机栈中入栈到出栈的过程。
  • 本地方法栈(Native Method Stack):它与Java虚拟机栈的作用类似,他们之间的不用点是:Java虚拟机栈是服务于执行Java方法(即字节码);而本地方法栈是服务于执行本地方法。
  • Java堆(Java Heap):它是JVM所管理的内存中最大的一块。Java堆是所有线程共享的的一块内存区域,在虚拟机启动时被创建。这个堆为一个的目的就是用来存放对象实例,几乎所有的对象实例都在这里分配内存。所以,从他的主要作用可以得出垃圾收集器会经常光顾这个区域,所以它也会被称为“GC堆”。从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以Java堆可以分为:新生代和老年代,再细致可以分为:Eden空间(伊甸园空间,最新的)、From Survivor空间(From 幸存者空间)、To Survivor空间(To 幸存者空间)[两个Survivor的存在是因为垃圾回收算法需要两个空间进行copying,这两个空间也是Eden空间到老年空间数据过渡的空间]、老年代[详情可参考:http://www.iteye.com/topic/894148]。这个堆在物理上可以不是连续的,只要逻辑上连续即可。堆的大小可以设置为可扩展,通过-Xmx和-Xms来指定堆得最大空间和最小空间,如果堆达到最大空间,并且无法继续扩展的时候,就会抛出OutOfMemoryError的异常。
  • 方法区(Method Area):与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、敞亮、静态变量、即时编译器编译后的代码等数据。虽然JVM规范把方法区描述为堆得一个逻辑部分,但是它却又一个别名叫做Non-Heap(非堆),目的就是为了与Java堆区分开来。更多人把这个区域称为“永久代”(Permanent Generation)。
  • 运行时常量池(Runtime Constant Pool):它是方法区的一部分。Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区运行时常量池中释放。
  • 直接内存(Direct Memory):在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道与缓冲区的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了Java堆和Native堆中来回复制数据。它不会受到Java堆大小的限制。
时间: 2024-10-22 07:19:24

深入理解JVM虚拟机(一):JVM运行时数据区的相关文章

JVM系列之四:运行时数据区

1. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 2. JDK1.7内存模型-运行时数据区域 根据<Java 虚拟机规范(Java SE 7 版)>规定,Java 虚拟机所管理的内存如下图所示. 1-3为线程私有,4-5为线程共享 1.程序计数器:为了线程切换后能恢复到正确的执行位置.线程私有2.Java虚拟机栈:虚拟机栈描述的是Java方法执行的内存模型:方法被调用时创建栈帧-->局部变量表->局部变量.对象

深入理解Java虚拟机读书笔记---运行时数据区域

运行时数据区域 1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖这个计数器来完成.由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令.因此,为了线

JVM(三)运行时数据区之本地方法栈

本地方法栈 Java虚拟机栈用于管理Java方法调用,本地方法栈用于管理本地方法的调用 本地方发栈也是线程私有 允许被实现成固定程度或者可动态扩展的内存大小(在OOM方面是相同的) 本地方法是C语言实现的 它的具体做法Native Method Stack 中等登记native方法,在Excution Engine执行时加载本地方法库 原文地址:https://www.cnblogs.com/Timeouting-Study/p/12512837.html

Java虚拟机学习--记录运行时数据区域

为方便后面学习的理解,记录一下! 运行时数据区 1.线程共享 1.1方法区(Method Area) 1.1.1运行时常量池(Runtime Constant Pool) 1.2堆(Heap) 2.线程私有 2.1虚拟机栈(VM Stack) 2.2本地方法栈(Native Method Stack) 2.3程序计数器(Program Counter Register) 3.直接内存(Direct Memory) 虚拟机栈: 线程私有,生命周期与线程同步,用来执行Java方法. 每个java方法

【JVM学习】2.Java虚拟机运行时数据区

来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题.但是,往往都会令我比较尴尬,我还话音未落,面试者就会"背诵"一段(Java虚拟机是由堆.方法区.虚拟机栈,吧啦吧啦...),估计心里还一脸自豪的想幸好哥提前在网上搜过,早有准备.每每这个时候,我都不忍心打断,因为"背诵"的真的太顺畅了! 这也怪不得面试者,首先Java虚拟机方面的知识,对中高级程序猿来说,工作中正面接触Java虚拟机的东西

Java虚拟机原理图解----JVM运行时数据区

     JVM运行时数据区(JVM Runtime Area) 其实就是指JVM在运行期间,其对计算机内存空间的划分和分配.本文将通过以下几个话题来讨论JVM运行时数据区. Topic 1. JVM运行时数据区 里有什么? Topic 2. 虚拟机栈 是什么?虚拟机栈 里有什么? Topic 3. 栈帧是什么?栈帧 里有什么? Topic 4. 方法区 是什么?方法区 里有什么? Topic 1.JVM运行时数据区里有什么? Topic 2. 虚拟机栈是什么?虚拟机栈里有什么? Topic 3

IT忍者神龟之 《Java虚拟机原理图解》JVM运行时数据区

[last updated :2014/11/7]      JVM运行时数据区(JVM Runtime Area)其实就是指JVM在运行期间,其对计算机内存空间的划分和分配.本文将通过以下几个话题来讨论JVM运行时数据区. Topic 1. JVM运行时数据区里有什么? Topic 2. 虚拟机栈 是什么?虚拟机栈里有什么? Topic 3.栈帧是什么?栈帧里有什么? Topic 4. 方法区是什么?方法区里有什么? Topic 1.JVM运行时数据区里有什么? Topic 2. 虚拟机栈是什

JVM运行时数据区--java虚拟机栈

虚拟机栈的背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令. 内存中的堆与栈 栈是运行时的单位,而堆是存储的单位1.栈解决程序的运行问题,即程序如何执行,或者说如何处理数据.堆解决的是数据存储的问题,即数据怎么放.放在哪儿. 2.一般来讲,对象主要都是放在堆空间的,是运行时数据区比较大的一块 3.栈空间存放 基本数据类型的局部变量,以及引用数据类型

深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)

了解Java GC机制,必须先清楚在JVM中内存区域的划分. JVM的体系结构如下:JVM的类加载系统.执行引擎系统.垃圾回收器都是去访问  运行时数据区. JVM管理的内存区域分为几个模块: (未完待续...)

JVM内存结构(运行时数据区)

前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些内存区域被统一叫做运行时数据区.Java运行时数据区大致可以划分为5个部分.在这里要特别指出,我们现在说的JVM内存划分是概念模型.如下图所示: JVM运行时数据区分为5种: 程序计数器 虚拟机栈(java栈) 堆 方法区 本地方法栈 程序计数器 程序计数器是一块较小的内存空间,它可