运行时数据区域

jvm在执行Java程序时会把他所管理的区域划分为若干个不同的数据区域,这些区域各有各自的用途。

如图:

1.程序计数器
       程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。每条线程都有一个独立的程序计数器,各线程之间的计数器互不影响。如果线程在执行一个java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址,在执行native方法时,计数器的值为空。并且在java虚拟机规范中没有在此区域规定任何的outOfMemoryError异常。
2.java虚拟机栈
       java虚拟机栈也是线程私有的,且生命周期和线程相同,其描述的是java方法执行的内存模型。在方法执行时,创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。此内存区域就是我们常说的栈内存。其中,局部变量表存放了编译器可知的各种基本数据类型。其中long和double占用两个局部变量空间,其他的占用一个。在进入方法时,此局部变量空间就被唯一确定。
       java虚拟机规范规定了两种异常状况:线程请求的栈深度大于虚拟机所允许的深度时,抛出StackOverflowError异常。如果扩展时,无法申请到足够的内存,抛出OutOfMemoryError异常。当然我们也可以设置系统允许分配的栈深度。
3.本地方法栈
       本地方法栈与java虚拟机栈类似,不过java虚拟机栈为虚拟机栈执行java方法服务,而本地方法栈则为虚拟机执行Native方法服务。Sun HotSpot虚拟机把本地方法栈和虚拟机栈合二为一。
4.java堆
       java堆是java虚拟机管理的内存在中最大的一块。是线程共享的。java堆也是垃圾回收的主要区域,因此很多时候也会被称为“GC堆”,并且现在的收集器都是采用的分代收集算法(GC算法介绍请看:http://www.cnblogs.com/Booker808-java/p/9063677.html),所以java堆还可以细分为新生代和老年代,新生代再细致点还可以分为Eden区、From Survivor区、To Survivor区,并且为了防止在线程共享下产生的分配区域的安全问题,java堆也会划分出多个线程私有的分配缓冲区(TLAB),其实吧,无论怎么划分,堆都是用来存储对象实例的,,之所以划分这么多区域,主要就是为了更高效的回收内存,更高效的分配内存。
5.方法区
       线程共享的区域,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等。方法区也是属于堆的一部分,但是为了区分开来,也可以叫做非堆这个区域的回收主要针对常量池的回收和对类型的卸载。当方法区无法满足内存分配需求时,会抛出OutOfMemoryError异常。
6.运行时常量池
       运行时常量池也是方法区的一部分,class文件除了含有类的版本、字段、方法、接口等描述信息外(这些信息都是通过十六进制的符号引用来代替的),还有一项就是常量池,专门用来存放编译期间生成的各种字面量(这里通常指final static声明的字段)和符号引用,这些符号引用一般都是描述什么字段类型信息啊、方法类型信息等,运行时常量对class文件常量池另一个重要的特征就是具备动态性,常量可以在运行时被放入常量池。
对象的创建
1.对象的创建
        java是个面向对象语言,语言层面上,是通过new关键字来进行创建对象的,但是在虚拟机中,创建对象又是个怎么样的过程呢??当new指令出来时,会去常量池中检查是否能定位到该类的符号引用,当检查通过之后,接下来就是为新生对象进行内存分配,等同于在堆中划分出一块区域。这时,问题来了,如果java堆中的内存是绝对完整的,所有的用过的内存都放在一边,没用过的放在另一边,中间放着一个指针作为分界点的指示器,那么分配内存的动作其实就是把那个指针指向空闲空间那边挪动一小块,这一小块就是属于我们对象的,这种分配方式属于“指针碰撞”。
        如果java堆内存是不完整的,是杂乱不堪的,这个时候指针碰撞根本不可能正常工作,,那么虚拟机就要维护一个列表,记录在堆上有哪些区域是可以被使用的,然后在分配内存时,在列表上找到一块足够大的空间分配给对象,同时更新列表上的记录。这种分配方式可以称为“空闲列表”,选取哪种方式完全取决于我们的堆的内存是否是规整的,而java堆是否规整又取决于垃圾收集器是否带有自动压缩整理功能。
2.并发下的内存分配
       在划分可用空间之外,还有一个很重要的因素就是,在多线程环境下(因为堆是线程共享的,所以这种情况是存在的),指针碰撞方式是存在线程安全问题的。当指针还在为线程A分配时(还没分配完),这时线程B又使用了原来的指针来分配内存。两种解决方式:
(1)采用同步的方式;
(2)把内存划分的动作按照不同的线程划分在不同的区域进行,就是说每个线程在堆上会预先分配好一小块私有的内存区域,称之为本地线程缓冲分配(TLAB)
哪个线程要分配内存,就在哪个线程的TLAB上划分,如果TLAB区域划分完了,就再进行同步,这样也可以内存划分时提高效率。

转载于:https://www.cnblogs.com/Booker808-java/p/9225706.html

JVM----Java内存区域相关推荐

  1. java内存区_基于jvm java内存区域的介绍

    jvm虚拟机在运行时需要用到的内存区域.广泛一点就是堆和栈,其实不然,堆和栈只是相对比较笼统的说法,真正区分有如下几个 先上图一: 总的就是 java的内存模型 内存模型又分堆内存(heap)和方法区 ...

  2. JVM Java内存区域 与 内存溢出 (系列号1)

    运行时数据区域 运行时的数据区域,就是JVM管理的内存区域.JVM 运行程序的时候,管理着运行时的内存(一般以静态的 main 方法进入本类的运行时数据区,几乎所有Java程序都是从此开始,也就是说这 ...

  3. JVM——Java内存区域相关3

    一. 垃圾收集算法 1. 标记-清除算法 缺点:1.效率低,标记和清除两个过程的效率都不高: 2.空间问题,标记清除后会产生大量的不连续内存碎片. 2. 复制算法 将内存分成三块:一块较大的Eden和 ...

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

    前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着 ...

  5. JVM最佳学习笔记一---Java内存区域与内存溢出异常

    2019独角兽企业重金招聘Python工程师标准>>> 前言 本笔记参照了周志明<深入理解Java虚拟机:JVM高级特性与最佳实践>第三版,读完之后受益匪浅,让我对Jav ...

  6. JVM - 结合代码示例彻底搞懂Java内存区域_对象在堆-栈-方法区(元空间)之间的关系

    文章目录 Pre 示例demo 总体关系 代码示例论证 反汇编 Pre JVM - 结合代码示例彻底搞懂Java内存区域_线程栈 | 本地方法栈 | 程序计数器 中我们探讨了线程栈中的内部结构 ,大家 ...

  7. JVM学习笔记(一):Java内存区域

    由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分.在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 首先Java源代码文件(. ...

  8. jvm(2)-java内存区域

    [0]README 0.1)本文转自 深入理解jvm, 旨在学习 java内存区域 的基础知识: [1]运行时数据区域 1)jvm 所管理的内存将会包括以下几个运行时数据区域 1.1)方法区:(线程共 ...

  9. 《深入理解JVM.2nd》笔记(二):Java内存区域与内存溢出异常

    文章目录 概述 运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 Java堆 方法区 运行时常量池 直接内存 HotSpot虚拟机对象探秘 对象的创建 第一步 第二步 第三步 第四步 最后一脚 ...

  10. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制--Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

最新文章

  1. 2022-2028年中国即时通讯市场投资分析及前景预测报告
  2. 邬贺铨院士:十问边缘计算!
  3. 3.6 判断两个链表是否相交
  4. CSS3 Media Queries详细介绍和使用实例
  5. 【git学习】git管理本地项目
  6. 安装mysql.dox_linux虚拟机上装mysql数据库-Go语言中文社区
  7. gsk meaning
  8. 求整数的位数及各位数字之和_如何判断正整数能否被7、4、8整除?(20年1月24日)...
  9. C语言实现哈希表(附完整源码)
  10. CXF学习(2) helloworld
  11. 微信公众号开发 ssl connect error
  12. android studio 2.3.1 r丢失,AndroidStudio中 R文件缺失的办法
  13. 为什么很多人上班好好的,却选择去创业?
  14. Recompile/upgrade nginx binary with no down-time
  15. nginx+thinkphp下解决不支持pathinfo模式以及存在的各种404,500问题
  16. Android之仿ele地图定位效果
  17. python 勒索病毒_lucky 勒索病毒分析与文件解密
  18. 后台任务列表 App 界面模糊处理
  19. python泰勒公式_泰勒展开式利用python数值方法证明
  20. 输入一个字符串,判断它的所有字符中否全部是大写字母,如不是,统计小写字母个数,并将其转换成大写字母后输出

热门文章

  1. 仿win8磁贴界面以及功能
  2. asp.NET自定义服务器控件内部细节系列教程五
  3. JavaScript 学习(2) - JS的内建对象
  4. Android应用程序目录结构框架搭建
  5. 微服务,微架构[五]之springboot读取properties文件
  6. 《实施Cisco统一通信管理器(CIPT1)》——2.2 CUCM:单站点部署模型
  7. 《Ruby程序员修炼之道》(第2版)—第1章1.2节剖析Ruby的安装
  8. nginx 安装与配置
  9. win8 远程桌面时提示凭证不工作问题的终极解决办法
  10. Solr在Weblogic中部署遇到的问题