Java虚拟机内存区域分为五部分:程序计数器、Java虚拟机栈、本地方法栈、堆、方法区。其中程序计数器、Java虚拟机栈、本地方法栈属于线程私有内存区,其生命周期与线程相同,随线程的产生而产生,随线程的消亡而消亡。这几个区域的内存在方法或线程结束时,自然就跟着回收了。因此这三个区域的内存分配和回收具有确定性,不需要考虑内存回收的问题。而Java堆和方法区属于线程共享内存区,所有线程都可以访问。只有在程序运行期间才能知道创建哪些对象,因此这两个区域的内存分配和回收都是动态的,也是垃圾收集器收集的主要区域。

下面分别介绍这五个区域。

1)       程序计数器

程序计数器是一块较小的内存空间,可以当做线程执行的字节码行号指示器。字节码解释器工作的时候就是通过改变程序计数器的值,来选取下一条所要执行的字节码指令,分支、跳转、循环、异常处理、线程恢复等都需要依赖程序计数器来完成。程序计数器是Java虚拟机中唯一不会发生内存溢出(OutOfMemoryError)的区域。

Java虚拟机的多线程是通过线程间的轮流切换并分配处理器执行时间的方式来完成的,任意时刻一个处理器只会执行一条线程中的指令。为了使线程切换后能恢复到正确的执行位置,每个线程都有一个独立的程序计数器,各线程之间独立存储、互不影响,因此是线程私有内存区。

2)       Java虚拟机栈

Java虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行结束都伴随着一个栈帧在虚拟机栈中从入栈到出栈的过程。

Java虚拟机栈也是线程私有内存区,生命周期与线程相同。基于栈的内存区域都可能发生两种异常:栈溢出和内存溢出。如果线程请求栈的深度大于虚拟机栈所允许的最大深度,并且无法扩展时,将会发生栈溢出(StackOverflowError)异常;如果可以扩展,在扩展时无法申请到足够的内存,将会发生栈溢出(OutOfMemoryError)异常。

局部变量表用于存放方法参数和方法内部定义的局部变量,其数据类型是编译期可知的各种基本数据类型、对象引用类型(reference)和返回(returnAddress)类型(它指向了一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成分配,即在Java程序被编译成Class文件时,就确定了所需分配的最大局部变量表的容量。当进入一个方法时,这个方法需要在栈中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

3)       本地方法栈

本地方法栈与虚拟机栈所发挥的作用非常相似,只是虚拟机栈为虚拟机执行Java方法服务(即程序员自己写的方法),而本地方法栈则为使用到的本地操作系统(Native)方法服务。本地方法栈也是基于栈,因此也会发生栈溢出或内存溢出异常。

4)       Java堆

Java堆是虚拟机所管理的最大一块内存,是所有线程共享的一块内存区域,在虚拟机启动时创建。Java堆用来存放对象实例,几乎所有的对象实例和数组都在这里分配内存。Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。

Java堆可以处于物理上不连续的内存空间中,只要逻辑上连续即可。在实现时,既可以是固定大小的,也可以是可扩展的,目前主流虚拟机都是可扩展的。如果在堆中没有足够的内存可分配,且无法扩展时,将会抛出内存溢出异常。

从垃圾收集的角度来看,Java堆还可以细分为新生代和老年代。新生代包括Eden、Survivor from、Survivor to,详情请见下面下面一章。

5)       方法区

方法区也是线程共享的内存区域,用于存储被虚拟机加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据。

和堆一样,方法区同样可以处于物理上不连续的内存空间中,只要逻辑上连续即可。在实现时,既可以是固定大小的,也可以是可扩展的。方法区可以不进行垃圾收集,相对而言,方法区的垃圾收集行为很少,主要是对常量池的回收和对类型的卸载。当方法区没有足够的内存完成分配时,会发生内存溢出异常。

平时所说的“永久代”(PermGen space)指的是方法区。

“运行时常量池”是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。运行时常量池具有动态性,常量既可以在编译期产生并进入常量池,也可以在运行期间进入常量池,常见的是String类的intern()方法。运行时常量池是方法区的一部分,因此也会发生内存溢出异常。

转载请注明出处 https://www.cnblogs.com/Y-oung/p/9762682.html

工作、学习、交流或有任何疑问,请联系邮箱:yy1340128046@163.com

Java虚拟机(JVM)内存区域的更多相关文章

  1. Java虚拟机------JVM内存区域

    JVM内存区域运行时数据区域分为两种: JVM内存区域 运行时数据区域分为两种: 线程隔离的数据区: 程序计数器 Java虚拟机栈 本地方法栈 所有线程程共享的数据区: Java堆 方法区 JVM 内 ...

  2. 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))

    java虚拟机的内存区域分配   在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...

  3. 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制

    一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...

  4. Java虚拟机之内存区域

    原创文章,转载请标明出处! 目录 一.背景 二.运行时内存区域概述 1.官方描述 2.中文翻译 3.内存区域简述 4.运行时数据区简图 5.运行时数据区详图 三.JVM线程 JVM数据区域与线程关系 ...

  5. Java虚拟机各内存区域的位置及功能的介绍

    Java虚拟机运行时数据区: 相关区域介绍: 程序计数器: 功能:当前线程所执行字节码的行号指示器.若是Java方法记录指令地址,若为Native方法,则不记录 隔离性:线程隔离 Error:无 Ja ...

  6. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  7. 深入理解Java虚拟机02--Java内存区域与内存溢出异常

    一.概述 我们在进行 Java 开发的时候,很少关心 Java 的内存分配等等,因为这些活都让 JVM 给我们做了.不仅自动给我们分配内存,还有自动的回收无需再占用的内存空间,以腾出内存供其他人使用. ...

  8. 深入理解Java虚拟机—JVM内存结构

    1.概述 jvm内存分为线程共享区和线程独占区,线程独占区主要包括虚拟机栈.本地方法栈.程序计数器:线程共享区包括堆和方法区 2.线程独占区 虚拟机栈 虚拟机栈描述的是java方法执行的动态内存模型, ...

  9. 深入Java虚拟机之内存区域与内存溢出

    一.内存区域 Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域.Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器.Java虚拟机栈.本地方 ...

  10. Java虚拟机JVM内存分区及代码执行机制

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt230 1.  JVM体系结构 图1 JVM体系结构    方法区:存放JVM ...

随机推荐

  1. SVN安装操作流程

    SVN 安装操作流程 1.服务端安装流程 1.1 双击打开svn-server安装包 1.2 点击Next 1.3 勾选上“I accert the terms in the License Agre ...

  2. 入职日志——Solomon

    心情 今天是所有培训结束后入职的第二天,紧张且期待. 紧张是因为昨天董经理有句话点醒了我. 你默默不再是个学生了.没有人会像你的老师父母一样担待你,原谅你. 职场是残酷无情的,是以结果为导向的.不论对 ...

  3. Struts2与Hibernate联合开发步骤

    hibernate与struts2的联合开发步骤: 1. 建立web工程 2. 加入jar包,struts2.hibernate.数据库连接的包 3. 数据表和bean之间的映射,以及相应的映射文件* ...

  4. zip 函数

    zip 函数,看上去是打包的意思,其实功能是将多个可迭代对象,组合成一个个元组. zip(iter1,iter2) a,b = zip(*zip(iter1,iter2)) a = [1,2,3] b ...

  5. 播放WAV文件和系统提示音

  6. csv文件已经python内置csv模块

    csv(Comma Separated Value,即逗号分隔值),文件以纯文本形式存储表格数据(数字和文本).可以用excel打开,并自动将每个逗号隔开的数据作为一列在excel中显示. pytho ...

  7. 记录一次Git问题及其解决方案

    错误信息:fatal: refusing to merge unrelated histories 错误产生背景:我将原先测试的项目本地删除后提交,然后将新的项目按照git的提交步骤进行提交,在最后一 ...

  8. mybatis动态sql语句学习(一)

    动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格 ...

  9. rabbitmq+topic+java

    可参照github代码:https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/EmitLogTopic.java 1. 新建m ...

  10. Keil开发的ARM程序main函数之前的汇编分析

    Keil开发的ARM程序main函数之前的汇编分析 ——BIN文件中RW段的数据移动 系统平台: STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储; FLASH地址范围 ...