版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习!

我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实例的时候,虚拟机要为对象分配内存,Java虚拟机又是如何配分内存的呢?这些都涉及到Java虚拟机的内存划分机制,今天我们就来探究一下Java虚拟机的内存模型。

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。根据Java虚拟机规范的规定,Java虚拟机所管理的内存包括以下几个数据区域。如下图所示:

以上就是Java虚拟机运行时数据区域的划分,每一块内存区域都有它的职责,存放着不同的运行时数据。

虚拟机栈

       Java虚拟机栈是线程私有的,每一个线程在这个区域都有一块所属的内存区域,它的生命周期与线程相同,随线程启动而生,随线程消亡而灭。虚拟机栈描述的是Java方法执行的内存模型,每一个线程都对应着虚拟机栈区域里的一个栈数据结构,由于一个线程的方法调用链可能会很长,每一个方法在执行时都会创建一个栈帧,栈帧就是线程对应的栈数据结构的栈元素,栈帧用于存储局部变量表、操作数栈、动态链接等信息。局部变量表存放了方法参数和方法内部定义的局部变量,包括各种基本数据类型和对象引用类型等信息。经常听到有的程序猿粗糙的把虚拟机内存划分为堆内存和栈内存,这种划分只能说明大多数程序猿比较关注的、与对象内存分配关系最密切的是这两块内存区域,其中的“栈内存”就是这里所说的虚拟机栈,而虚拟机栈里我们程序猿最为关注的就是局部变量表部分。

本地方法栈

       本地方法栈也是线程私有的,它与虚拟机栈发挥的作用相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法(本地方法)服务。在Java虚拟机规范中并没有对本地方法栈的实现做强制规定,有的虚拟机甚至直接把虚拟机栈和本地方法栈合二为一。

       Java堆是所有线程所共享的一块内存区域,也是Java虚拟机所管理的内存中最大的一块。这块内存的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java堆是垃圾收集器管理的主要区域,从内存回收的角度看,由于现在收集器基本都采用分代收集算法,所以Java堆还可以细分为新生代和老年代。新生代还可以再细分为Eden区域、FromSurvivor区域和ToSurvivor区域。无论怎么划分,都与存放的内容无关,存储的任然都是对象实例。进一步划分的目的是为了更好的回收或者更快的分配内存。

方法区

       方法区与Java堆一样,是线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据。方法区是一个逻辑区,具体属于哪一块物理内存根据不同的虚拟机实现而定。在HotSpot的实现中,方法区逻辑上与堆内存隔离,物理存储上却是是属于Java堆的一部分。很多人把方法区称为“永久代”,其实是HotSpot使用永久代来实现方法区而已。其他的虚拟机实现并没有永久代这一概念。Java虚拟机规范对方法区的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾回收。一般来说不会在方法区进行垃圾回收,在这一区域进行回收的效果很难让人满意。当方法区无法满足内存分配需求时会抛出内存溢出异常。

运行时常量池是方法区的一部分,用于存放编译期间生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存储。

程序计数器

       程序计数器是一块很小的内存空间,它也是线程私有的。它可以看作是当前线程所执行的字节码的行号指示器,通过改变这个计数器的值来选取下一行需要执行的字节码指令。由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器内核只会执行一条线程中的指令,因此,为了线程切换后能够恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间互不影响,独立存储。

以上就是Java虚拟机的内存模型划分,这是我们程序猿必须掌握的原理,弄清Java虚拟机的内存模型,是理解虚拟机内存分配和垃圾回收的基础,以此作为总结。

Java虚拟机:内存模型详解的更多相关文章

  1. Java虚拟机内存分配详解

    简介 了解Java虚拟机内存分布的好处 1.了解Java内存管理的细节,有助于程序员编写出性能更好的程序.比如,在新的线程创建时,JVM会为每个线程创建一个专属的栈 (stack),其栈是先进后出的数 ...

  2. Java虚拟机内存区域详解

    JVM 运行时的数据区域 首先获取一个直观的认识: 总共也就这么 5 个区(直接内存不属于 JVM 运行时数据区的一部分),除了程序计数器其他的地方都有可能出现 OOM (OutOfMemoryErr ...

  3. 云时代架构阅读笔记六——Java内存模型详解(二)

    承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...

  4. Java虚拟机内存模型及垃圾回收监控调优

    Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...

  5. Java虚拟机--内存模型与线程

    Java虚拟机--内存模型与线程 高速缓存:处理器要与内存交互,如读取.存储运算结果,而计算机的存储设备和处理器的运算速度差异巨大,所以加入一层读写速度和处理器接近的高速缓存来作为内存和处理器之间的缓 ...

  6. flink内存模型详解与案例

    任务提交时的一些yarn设置(通用客户端模式) 指定并行度                        -p 5 \ 指定yarn队列                     -Dyarn.appl ...

  7. Java 内存模型详解

    概述 Java的内存模型(Java Memory Model )简称JMM.首先应该明白,Java内存模型是一个规范,主要规定了以下两点: 规定了一个线程如何以及何时可以看到其他线程修改过后的共享变量 ...

  8. JMM内存模型详解(一)

    本文开始死磕JMM(Java内存模型)由于知识点较多,分来写 该文为JMM第一篇 技术往往是枯燥的,本文文字较多 1. JMM是什么? 其实JMM很好理解,我简单的解释一下,在Java多线程中我们经常 ...

  9. 云时代架构阅读笔记五——Java内存模型详解(一)

    什么是Java内存模型 Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的访问差异,以实现让Java程序在各种平台下都能达到一致 ...

随机推荐

  1. Cohort Analysis and LifeCycle Grids mixed segmentation with R(转)

    This is the third post about LifeCycle Grids. You can find the first post about the sense of LifeCyc ...

  2. 2017-5-29 Excel VBA 小游戏

    ---恢复内容开始--- 转一个Excel VBA的小游戏,最近对excel有了更深入的了解,功能很强大,也刷新了我对待事情的态度. 一.准备界面 我们先来把游戏界面准备好,选中前4行,行高调成50, ...

  3. python 字典的常见操作

    字典 字典的增删改查 字典的创建方式: # 创建字典类型 info = { 'name':'李白', ', 'sex':'男' } msg = { 'user01':'Longzeluola', 'u ...

  4. eclipse 创建maven 项目 动态web工程报错

    Eclipse 创建maven 项目 动态web工程 注:Eclipse版本为(Version: Mars.1 Release (4.5.1))maven版本为(apache-maven-3.3.9) ...

  5. asp.net MVC 网站图片防盗链的几种方法

    目录 1. 通过 URL Rewrite Module 组件 2. 通过 nginx 图片防盗链 3.自定义 HttpHandler 处理 4. 通过 MVC 自定义路由规则防盗链 5. 通过 MVC ...

  6. lucene全文搜索之一:lucene的主要功能和基本结构(基于lucene5.5.3)

    前言:lucene并不是像solr或elastic那样提供现成的.直接部署可用的系统,而是一套jar包,提供了一些常见语言分词.构建索引和创建搜索器等等功能的API,我们常用到的也就是分词器.索引目录 ...

  7. DNS分析之 dnsdict6 使用方法

    基本用法就是: dnsdict6 -d46 -t 10 baidu.com

  8. oracle日志挖掘

    oracle日志挖掘是一种十分强大的数据恢复技术,只要你保障你的归档日志和重做日志是完整的,那么就可以将你的数据恢复到任何时刻.简单叙述一下日志挖掘的基本原理,然后进行一个简单的小实验. 日志挖掘时基 ...

  9. 学习总结------Servlet的简单理解

    1.什么是Servlet Servlet是一个Java编写的程序,在服务器端运行的(如tomcat) Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览 ...

  10. 理解Java中的抽象

    在计算机科学中,抽象是一种过程,在这个过程中,数据和程序定义的形式与代表的内涵语言相似,同时隐藏了实现细节. 抽象:一个概念或者想法不和任何特定的具体实例绑死. 目录 什么是抽象 抽象的形式 如何在J ...