JVM基础--JVM内存区域模型

  一提到Java,我们第一直觉就是Java语言。其实Java不仅仅是一种编程语言,它还是由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并且广泛应用于嵌入式系统/移动终端/企业服务器/大型机等场合。从广义上讲,类似于JRuby等运行在JVM上的语言及其相关的程序都属于Java技术体系中的一员。但是,一般咱们从传统上理解,sun官方所定义的Java技术体系包括:Java程序设计语言/各个平台上的JVM虚拟机/class文件/Java API类库/还有第三方Java类库。我们把JVM JavaAPI 和Java程序设计语言这三部分称为JDK。

  简单介绍了Java之后,就进入今天的主题,jvm内存区域模型。相对于c或者c++来说,Java的自动内存机制可以每次new对象写配对的delete/free代码。不容易出现内存溢出和内存泄漏的情况。同样,有利肯定就有弊处。一旦出现内存泄漏或者内存溢出的情况,排查问题也是一项棘手的工作。

  JVM在执行Java程序时,会把Java虚拟机管理的内存划分不同的数据区域。每个区域都有自己的用途。如下图所示:

这张图就表示了Java虚拟机运行时数据区。下面我们就来一一介绍着不同区域的内容。

程序计数器

  程序计数器program counter register , 是一块较小的内存空间。我们可以把它当前线程所执行的字节码的行号指示器。

而在虚拟机的概念模型中,字节码解释器,是通过改变这个程序计数器的值,来选去下一条需要执行的字节码指令。一些基础功能,比如分支/循环/跳转/异常处理/线程恢复等,就是得需要这个计数器才能完成。

  Java虚拟机中的多线程就是 通过线程轮流切换 并 分配处理器执行时间 的方式来实现。在任何一个时间内,一个处理器也只能执行一个线程中的指令。所以,线程之间是来回切换的,为了线程切换后能恢复到正确的执行位置。所以每条线程都配置了一个专用的独立的 程序计数器。这样,各个线程的程序计数器之间不会相互干扰,独立存储。我们称之为“线程私有”内存。

Java虚拟机栈

Java虚拟机栈 VM stack,就是执行Java方法的内存模型。这个也是线程私有的,生命周期跟线程一致。

每个Java方法被执行的时候,都会创建一个“栈帧” ,用于存储 局部变量表 和 操作数栈 和 动态链接 和局部变量区 等信息

每个Java方法从被调用 到 执行完 这个过程,就对应着一个栈帧在虚拟机栈中 从入栈 到 出栈的过程。

下图是关于一个“栈帧”的示意图:

其中值得注意的是,栈帧中的局部变量表:局部变量区所需要的内存空间,是在编译期间就完成分配的。当进入一个方法是,这个方法需要在帧中分配多大的局部变量空间是完全确定的。方法在运行期间,是不会改变局部变量表的大小。

本地方法栈

本地方法栈 native method stack ,与上面介绍的虚拟机栈基本类似。区别之处在于:上面的虚拟机栈  为执行Java方法的内存模型,而本地方法栈 是为native方法也就是操作系统提高的方法 服务的。有的虚拟机(如sun Hotspot虚拟机),就直接把本地方法栈和Java虚拟机栈合并在一起。

Java堆

原文地址:https://www.cnblogs.com/starstarstar/p/8723456.html

时间: 2024-10-13 06:27:23

JVM基础--JVM内存区域模型的相关文章

【Java高级】JVM内存区域模型和加载过程

JVM内存区域模型 1.方法区 也称"永久代" ."非堆",  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内存区域.默认最小值为16MB,最大值为64MB,可以通过-XX:PermSize 和 -XX:MaxPermSize 参数限制方法区的大小. 运行时常量池:是方法区的一部分,Class文件中除了有类的版本.字段.方法.接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种符号引用,这部分内容将在类加载后放到方法区的运行时常量池中.

JVM内存区域模型

一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆” ,"perm",  它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内存区域.默认最小值为16MB,最大值为64MB,可以通过-XX:PermSize 和 -XX:MaxPermSize 参数限制方法区的大小. 类太多有可能撑爆永久区:如加入JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M,运行后会报如下异常: Exception in

【深入理解Java虚拟机】Java内存区域模型、对象创建过程、常见OOM

本文内容来源于<深入理解Java虚拟机>一书,非常推荐大家去看一下这本书.最近开始看这本书,打算再开一个相关系列,来总结一下这本书中的重要知识点.呃呃呃,说好的那个图片请求框架呢~  不要急哈,因为这个请求框架设计的内容还是比较广的,目前业余时间正在编写当中,弄好了之后就会放上来.在完成之前,咱还是先来学习一下其他知识. 1.内存模型 java虚拟机在执行java程序的过程中会把它说管理的内存划分为若干个不同的数据区域,如下图所示: 图片来源于网络 (1)程序计数器(Program Count

深入理解jvm之一【内存区域】

文章开始之前,首先需要申明,本系列文章讨论的是HotSpot VM,文章中多数观点基于<深入理解Java虚拟机:JVM高级特性与最佳时间   周志明>,笔者如有理解错误,欢迎指正. 在开始探索jvm虚拟机之前,不得不对jvm的内存区域进行讨论,依旧先附上图表: 程序计数器 程序计数器,也能叫做PC寄存器,从名字上来理解可能会把它想成一个计数的内存区域,但是,了解汇编的人会知道,程序技术器实际上是CPU上的一个寄存器,它保存当前指令执行的地址(也可以说下一条指令所在的存储单元).当cpu执行该线

学习jvm(一)--java内存区域

前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着重讲解垃圾回收这一章节,该章节涉及了垃圾的标记算法以及各种垃圾回收算法,然后大概的介绍下市面上使用的垃圾收集器.之后就总结下上面的原理,讲解相关的jvm调优案例.然后会着重讲解类加载过程.最后一章讲字节码的部分,字节码相对来说是比较枯燥而且特别繁琐的内容,最好是自己动手配合着学习会好一点,或者观其大

深入理解JVM(一)--Java 内存区域

一.  运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. Java虚拟机所管理的内存将会包括以下几个运行时数据区域:                                   1. 程序计数器 1)程序计数器(Program CounterRegister) 是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器. 在虚拟机的概念模型里, 字节码解释器工作时就是通过改变这个计数器的值来选去吓一跳需要执行的字节码指

JVM笔记3-java内存区域之运行时常量池

1.运行时常量池属于线程共享区中的方法区. 2.运行时常量池用于编译期生成的各种自变量,符号引用,这部分内用将在类加载后接入方法区的运行时常量池中存放. 看如下代码所示,如图: public class Test { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System

JVM基础--JVM参数之堆栈空间配置

目录 堆配置 年轻代 Eden区 永久代(JDK1.7) 元空间(JDK1.8) 栈空间 直接内存 总结 参考资料 JVM系列目录 JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips:本文所有配置,如无特别说明,均基于JDK1.8. 堆配置 我们使用 -Xms 设置堆的初始空间大小,使用 -Xmx 设置堆的最大空间大小. java -Xms20m

JVM虚拟机(一) 内存区域

JVM虚拟机内存组成: 如下图: 1. 程序计数器: (1)是一块较小的内存空间:可以看做当前程序执行子界面的行号指示器,字节码解析器执行的时候就是根据这个判断下一条指令该执行什么. (2)因为cpu在执行代码的时候,会在多个线程之间进行切换执行,所以为了在cup切换后恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各线程之间互不影响,独立存在,我们称此类内存为"线程私有"的内存. (3) 如果当前cup执行的是java代码,这个计数器是记录的是正在执行的虚拟机字节码的地址:如