在读正文之前,阅读以下两篇博客学习并理解堆栈、作用域、本地方法的概念。

作用域:https://www.cnblogs.com/AlanLee/p/6627949.html

操作数栈:https://denverj.iteye.com/blog/1218359 (必读)

堆内存和栈内存:https://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html (必读)

一、区域划分(包含5个区域,其中程序计数器、虚拟机栈、本地方法栈为线程私有的,堆和方法区是线程共享的)

JVM在执行程序时,将内存划分为若干个不同的数据区域。

将这些区域分为两类:1.线程私有的数据区域 2.所有线程共享的数据区域

1.线程私有的数据区域

线程私有的意思是:该数据区域随着单个线程的启动而建立,当该线程结束后这个私有数据区域也被销毁。各线程的私有线程互不影响,独立存在。

(一)程序计数器

通常的程序计数器(PC)是计算机CPU中的一个重要部件,它存储着CPU要执行的命令的地址。在计算机从通电到断电这期间,CPU做的事儿也就是不断执行程序计数器指向的指令和更新程序计数器的值使之指向下一条要执行的指令。

Java虚拟机中的程序计数器是Java运行时数据区中的一小块内存区域,但是它的功能和通常的程序计数器是类似的,它指向虚拟机正在执行字节码指令的地址(行号)。具体点儿说,当虚拟机执行的方法不是native的时,程序计数器指向虚拟机正在执行字节码指令的地址;当虚拟机执行的方法是native的时,程序计数器中的值是未定义的。另外,程序计数器是线程私有的,也就是说,每一个线程都拥有仅属于自己的程序计数器。

顺便提一下:java文件是通过编译器被编译成字节码文件的,这个编译器就是javac,这就是JDK和JRE的区别之一,JDK是开法工具包,包括了编译器javac;而JRE是运行环境,不需要包含编译器。

JVM中的程序计数器和CPU中的程序计数器的区别在于:前者指向这个在指向的字节码的行号,而后者指向下一条将被执行的指令的地址。

(二)Java虚拟机栈(方法执行的内存模型栈)

一个线程的虚拟机栈包含着多个栈帧,每个方法在执行时都会创建一个栈帧,它的栈帧里包含着它的局部变量表、操作数栈、动态链接、方法的返回地址等信息。一个方法的被调用和执行完成的时,分别对应着栈帧的创建和入栈、出栈。

局部变量表:

主要用于存储方法中的局部变量,包括方法的局部变量信息和方法的参数信息。如各种基本数据类型的数据以及引用类型。

这里特别指出:引用类型即Reference类型,它不等于对象的本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表

对象的句柄或其他与此对象相关的位置。

操作数栈:

不同于程序计数器,Java虚拟机没有寄存器,程序计数器也无法被程序指令直接访问。Java虚拟机的指令是从操作数栈中而不是从寄

存器中取得操作数的,因此它的运行方式是基于栈的而不是基于寄存器的。虽然指令也可以从其他地方取得操作数,比如从字节码流中

跟随在操作码(代表指令的字节)之后的字节中或从常量池中,但是主要还是从操作数栈中获得操作数。

虚拟机把操作数栈作为它的工作区,程序中所有的计算过程都是在借助操作数栈来完成的,大多数指令都是要从这里弹出数据,执行运

算后将运算结果压回操作数栈。 和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。但是和前者不同的是,它不是通

过索引来访问,而是通过标准的栈操作—压栈和出栈—来访问的。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。

动态链接:

Class 文件中存放了大量的符号引用,字节码中的方法调用指令就是以常量池中指向方法的符号引用作为参数。这些符号引用一部分会

在类加载阶段或第一次使用时转化为直接引用,这种转化称为静态解析。另一部分将在每一次运行期间转化为直接引用,这部分称为动态

连接。

 方法返回地址:

当一个方法执行完毕之后要回到调用它的地方,因此在栈帧中必须保存一个方法返回地址。

(三)本地方法栈

java native方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言直接操纵计算机硬件时要声明为native方法。

通常的程序计数器(PC)是计算机CPU中的一个重要部件,它存储着CPU要执行的命令的地址。在计算机从通电到断电这期间,CPU做的事儿也就是不断执行程序计数器指向的指令和更新程序计数器的值使之指向下一条要执行的指令。

Java虚拟机中的程序计数器是Java运行时数据区中的一小块内存区域,但是它的功能和通常的程序计数器是类似的,它指向虚拟机正在执行字节码指令的地址。具体点儿说,当虚拟机执行的方法不是native的时,程序计数器指向虚拟机正在执行字节码指令的地址;当虚拟机执行的方法是native的时,程序计数器中的值是未定义的。另外,程序计数器是线程私有的,也就是说,每一个线程都拥有仅属于自己的程序计数器。

2.线程共享的数据区域

(一)堆(Heap)

栈存储的是基本类型的变量和引用类型的变量,而堆中存放的通过new关键字产生的对象和数组。从存取速度上来讲,栈比堆更快,但是不够灵活,堆之所以慢是因为每次存取都是动态的。记住一点:堆可以处于物理位置不连续的内存空间中,只要逻辑上是连续的就可以了。

(二)方法区

方法区用于存储已被虚拟机加载的类信息、常量、静态变量以及被编译器编译后的class字节码文件。class字节码文件包含常量池,而当class文件被类加载时,class文件中的常量池中的字面量和符号引用就会别加载到运行时常量池中。

Java Core - JVM运行时内存管理的更多相关文章

  1. JVM 运行时内存结构

      1.JVM内存模型       JVM运行时内存=共享内存区+线程内存区 1).共享内存区       共享内存区=持久带+堆       持久带=方法区+其他       堆=Old Space ...

  2. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

  3. JVM运行时内存组成分为一些线程私

    JVM运行时内存组成分为一些线程私有的,其他的是线程共享的. 线程私有 程序计数器:当前线程所执行的字节码的行号指示器. Java虚拟机栈:java方法执行的内存模型,每个方法被执行时都会创建一个栈帧 ...

  4. [转]JVM运行时内存结构

    [转]http://www.cnblogs.com/dolphin0520/p/3783345.html 目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的 ...

  5. Jvm运行时内存解析

    一.jvm的概念 在了解jvm的概念之前,我们先来了解java平台的逻辑结构,图片来自<深入java虚拟机> 从图中我们可以看到jdk包含了jre,java语言和java开发工具和Api, ...

  6. 详细了解JVM运行时内存

    详细了解JVM运行时内存 1.程序计数器 概念 程序计数器也叫作PC寄存器,是一块很小的内存区域,可以看做是当前线程执行的字节码的行号指示器.字节码的解释工作就是通过改变程序计数器里面的值来获得下一条 ...

  7. JVM02——JVM运行时内存

    在上一篇文章中,我们介绍了 JVM 的内存区域,本文我们将继续围绕 JVM 展开话题,介绍 JVM 运行时内存.关注我的公众号「Java面典」了解更多 Java 相关知识点. Java 堆从 GC 的 ...

  8. 基础篇:JVM运行时内存布局

    目录 1 JVM的内存区域布局 2 JVM五大数据区域介绍 3 JVM运行时内存布局和JMM内存模型区别 4 JMM内存模型交互操作 欢迎指正文中错误 关注公众号,一起交流 参考文章 1 JVM的内存 ...

  9. Java(JVM运行时)各种内存区域详解及扩展

    本文整理于  Java内存与垃圾回收调优 Java 堆内存 从几个sample来学习Java堆,方法区,Java栈和本地方法栈 首先来一张图让我们理清楚java运行时状态: 诚然,如上图所示:java ...

随机推荐

  1. Linux中“!"的神奇用法

    前言 实际上,不起眼的“!”在linux中有着很多让你惊叹的妙用.本文就来细数那些“!”的神奇用法. 执行上一条命令 例如,在执行完上面一条命令后,可以使用下面的方式再次执行上一条命令: $ wher ...

  2. 让EntityFramework.Extended支持MySql

    EF:Entity Framework EFEL:Entity Framework Extended Library EFEL5.0时代是不支持MySql的,现在升级到6.0之后,已经支持MySql了 ...

  3. Ubuntu 普通用户无法启动Google chrome

    删除 /home/你的用户名/.config/google-chrome文件,再打开就好了 root@ecos:cd /home/ecos/.config root@ecos:~/.config# r ...

  4. grep正则表达式搜索

    grep -n -e "INT32 *AdaptorPrmOp" --include "*.c"  -r ./ 搜索函数的定义 中间有n个空格

  5. MySQL高级知识系列目录

    MySQL高级知识(一)——基础 MySQL高级知识(二)——Join查询 MySQL高级知识(三)——索引 MySQL高级知识(四)——Explain MySQL高级知识(五)——索引分析 MySQ ...

  6. Java基础知识点(一)

    前言:本篇随笔,主要记录Java的基础知识点,不管是用于项目或者面试中,笔者认为都非常有用,所以将持续更新...... 1.Java的访问权限 Java中有四种访问权限:默认访问权限.public.p ...

  7. php面试中的经典问题

    原文:https://blog.csdn.net/ghostlv/article/details/51284745 问题一问题描述考虑下面代码: $str1 = 'yabadabadoo';$str2 ...

  8. 【ES6】export和important使用区别

    export命令 export { name1, name2, …, nameN }; export { variable1 as name1, variable2 as name2, …, name ...

  9. 微信硬件平台(一) 公众号 ESP8266 Arduino LED

    微信硬件平台 本文目的,使用微信公众号控制ESP8266的LED开和关.进一步使用微信当遥控器(避免写APP或者IOS或者小程序),控制一切设备.给两个关键的总教程参考. 官网教程  微信硬件平台 微 ...

  10. 微服务框架surging学习之路——序列化 (转载https://www.cnblogs.com/alangur/p/10407727.html)

    微服务框架surging学习之路——序列化   1.对微服务的理解 之前看到在群里的朋友门都在讨论微服务,看到他们的讨论,我也有了一些自己的理解,所谓微服务就是系统里的每个服务都 可以自由组合.自由组 ...