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. WAKE-WIN10-SOFT-环境

    操作系统名称 Microsoft Windows 10 专业版版本 10.0.14393 版本 14393其他操作系统描述 没有资料操作系统制造商 Microsoft Corporation系统名称 ...

  2. asp.net mvc 4.0常见的几个问题

    看书的时候遇到很多不知所云的错误,都是在网上找到的解决方法,没办法,从asp.net到mcv很多的新技术,没有一点思路,只能在网上搜罗了. 1.更新产品不成功 更新产品的时候一直不能更新成功,但是很奇 ...

  3. 郝斌 SqlServer2005 学习笔记

    1.0 什么是数据库 狭义:存储数据的仓库. 广义:可以对数据进行存储和管理的软件以及数据本身统称为数据库. 另外一种说法:数据库是由表.关系.操作组成. 2.0 为什么要学习数据库 几乎所有的应用软 ...

  4. CF839D Winter is here

    题目分析 显然我们不可能直接计算每一个子序列的贡献,而应该计算对于每一个gcd对答案的贡献. 考虑容斥.按照套路: 设\(q(i)\)表示序列\(gcd\)为\(i\)的倍数的序列长度和. 设\(g( ...

  5. css层叠样式表总结

    一.css css里注释只有一种 /*  */ 二.css与HTML四种结合方式 1.行内样式 在标签中加入style属性 内部的写法:key1:value;key2:value; <div s ...

  6. [19/04/04-星期四] IO技术_CommonsIO(通用IO,别人造的轮子,FileUtils类 操作文件 & IOUtilsl类 操作里边的内容 )

    一.概念 JDK中提供的文件操作相关的类,但是功能都非常基础,进行复杂操作时需要做大量编程工作.实际开发中,往往需要 你自己动手编写相关的代码,尤其在遍历目录文件时,经常用到递归,非常繁琐. Apac ...

  7. MSF入侵安卓手机

    MSF是Metasploit的简称,Metasploit是一款开源的安全漏洞检测工具,非常强大,分别有Windows版和Linux版,工具里集成了许多微软公布的漏洞(0day). 我这里做测试的系统是 ...

  8. log4net快速使用流程

    以下内容大部分来自这里,对原作者流子表示感谢 1.Nuget安装,当前版本2.0.8 2.创建log4net.config文件,文件内容如下: <?xml version="1.0&q ...

  9. Sonar安装和常见问题解决

    Sonar是一款代码质量分析工具,有助于帮助代码质量提高. Sonar的官网地址为:https://www.sonarqube.org/downloads/ 点击 Show All Versions ...

  10. 面试准备——(二)专业知识(2)Python

    面试遇到的问题: 滴滴: 1. Python的数据结构 2. list和tuple的区别 3. list中有哪些操作?append和extend的区别? 4. list和dict的却别?dict是有序 ...