一、运行时数据区

程序计数器(线程私有)

1.程序计数器占用jvm内存较小,主要用来记录当前线程所执行的字节码的位置,因为jvm的多线程都是通过cpu对线程进行来回切换,所以在某个确定的时间cpu只会执行一个线程,为了频繁的线程切换后各线程都能找到自己之前执行的准确位置,所以每条线程都维护了一个独立的程序计数器,互不干扰;

2.该区域是java虚拟机规范中唯一一个没有规定任何oom的内存区域

虚拟机栈(线程私有)

1.每个线程都会创建一个虚拟机栈,标识java方法执行的内存模型,每个方法执行的时候虚拟机都会为其生成一个栈帧,用来存储局部变量表、操作数栈、动态链接、方法出口等信息;每个方法被调用到其执行完毕的过程就对应一个栈帧从入栈到出栈的过程。虚拟机栈的生命周期和线程是相同的

2.虚拟机栈是一个先进后出的,栈顶的栈帧称为当前栈帧,虚拟机只会操作处于栈顶的栈帧

3.局部变量表

局部变量表用于记录执行该方法时会使用到的变量值,其主要存放了编译期可知的各种java基本数据类型,对象的引用以及return adress(指向了一条字节码引用的地址),

本地方法栈

与虚拟机栈作用相似,其执行的是本地方法而不是java方法

堆(线程共享)

用于存储对象实例,可固定大小,也可动态扩展,通过-Xmx和-Xms来设置堆分配到内存的最大值和初始值

方法区(线程共享)

用于存储已被虚拟机加载的类型信息,常量,静态变量,及时编译器编译后的代码缓存等数据

二、对象的创建

新对象的内存分配

当new一个新的对象时,通常有两种方式为新对象分配内存空间,一种是指针碰撞法,该方法使用的前提是堆内存是规整的,所有已用的内存在一边,没被使用的内存在另一边,中间放一个指针作为分界点的标记,当需要为一个新对象分配内存时,只需将指针向没被使用的内存那侧移动对应的距离即可;另一种方式是空闲列表,当堆内存不规整且已用和未用内存混乱交错时使用,需要虚拟机维护一个列表来记录哪些内存是可用的,当需要为一个新对象分配内存时,从列表里找到对应的空间分配给该对象,然后更新列表上的记录;

堆内存是否规整则需要根据其使用的垃圾收集器是否有压缩整理的能力而决定,像Serial,ParNew等带压缩整理过程的收集器采用的内存分配算法就是指针碰撞;像CMS这种基于清楚算法的收集器理论上只能采用空闲列表的方法(为什么是理论上详见深入理解JVM虚拟机 第三版 P48);

如何在并发下保证内存分配的线程安全

由于内存分配的频繁性,当需要给对象A分配内存,指针还没移动B对象进来了且使用了原本要给A用的那块内存,所以会存在安全隐患,解决这类并发下内存分配的安全问题有如下两种方法

-对分配内存的动作做同步处理,实际上虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性

-TLAB(分配缓冲)将分配内存的操作按照线程划分在不同空间,即每个线程在堆中预先分配一小块内存,当哪个线程要分配内存时就去其自己线程所在的缓冲区分配,这样各线程互不干扰,确保了并发下的安全性;只有当线程的本地缓冲区用完了分配新的缓冲区时才需要同步锁定,可以通过-XX:+/-UseTLAB命令来开启/关闭是否启用缓冲区

三、对象的构成

对象在堆中的存储布局主要有以下三个部分:

1.对象头(大小刚好是8的整数倍)

对象头包含两类信息,一类用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等;另一类是类型指针,即对象指向它的类型元数据的指针,java虚拟机通过这个指针来确定该对象是那个类的实例;

2.实例数据

实例数据是对象存储的有效信息,也就是代码里定义的各种类型的字段内容,无论是父类继承的还是子类中定义的字段都必须记录起来

3.对齐填充

HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,因为对象头已被设计成刚好是8的整数倍,所以当实例数据没有与8的整数倍对齐时,需要对其填充

四、对象的访问定位

1.句柄访问

堆中划分一块内存作为句柄池,里面包含了对象的实例数据指针和类型数据指针,该指针指向堆或方法区中各自具体的地址信息,而栈中的本地变量表中的对象的引用指向堆中的句柄池,这样对象寻址的时候由栈中的引用首先找到句柄池中该对象的指针,再去找具体的存储地址;

2.直接指针访问

栈中的本地变量表中的引用直接指向堆中对象的地址,但是对象在堆中的布局就必须考虑如何放置对象类型数据的相关信息;

jvm之自动内存管理的更多相关文章

  1. JVM介绍&自动内存管理机制

    1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...

  2. 深入理解JVM(一) -- 自动内存管理机制

    Java运行时数据区域分为:程序计数器,虚拟机栈,本地方法栈,Java堆,方法区,运行时常量池,直接内存,结构如下: 1.程序计数器: 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示 ...

  3. JVM探索之——内存管理(一)

    本系列的第一篇文章,预计本系列最后面会有两三个案例. Java与C.C++不一样Java不需要Coder进行手动内存管理,而这一切都交给JVM进行自动内存管理,这从某种程度上来说也减轻了我们Coder ...

  4. JVM自动内存管理学习笔记

    对于使用 C.C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任.对于 Java 程 ...

  5. JVM自动内存管理-Java内存区域与内存溢出异常

    摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...

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

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

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

    一.JVM运行时数据区域概述 Java相比较于C/C++的一个特点就是,在虚拟机自动内存管理机制的帮助下,我们不需要为每一个操作都写像C/C++一样的delete/free代码,所以也不容易出现内存泄 ...

  8. JVM自动内存管理机制--读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...

  9. JVM | 第1部分:自动内存管理与性能调优《深入理解 Java 虚拟机》

    目录 前言 1. 自动内存管理 1.1 JVM运行时数据区 1.2 Java 内存结构 1.3 HotSpot 虚拟机创建对象 1.4 HotSpot 虚拟机的对象内存布局 1.5 访问对象 2. 垃 ...

随机推荐

  1. 大家都能看得懂的源码 - ahooks 是怎么处理 DOM 的?

    本文是深入浅出 ahooks 源码系列文章的第十三篇,该系列已整理成文档-地址.觉得还不错,给个 star 支持一下哈,Thanks. 本篇文章探讨一下 ahooks 对 DOM 类 Hooks 使用 ...

  2. 关于rt-thread调度器实现的底层代码分析

      本文使用了rt-thread自带的钩子函数和显示函数进行了实验,从rt-thread自带的延时函数rt_thread_delay()函数入手,对rt-thread系统的调度器进行分析.主要参考资料 ...

  3. 简单创建一个SpringCloud2021.0.3项目(二)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上一篇教程 3. 创建公共模块Common 4. 网关Gateway 1. 创建Security 2. Security登陆配置 3 ...

  4. KingbaseES R3 集群cluster日志切割和清理案例

    案例说明: 对于KingbaseES R3集群的cluster日志默认系统是不做切割和清理的,随着运行时长的增加,日志将增长为一个非常大的文件,占用比较大的磁盘空间,并且在分析问题读取大文件时效率很低 ...

  5. Mac_mysql_密码重置

    1 通过Mac 的设置 stop mysql 2 跳过权限认证 // 进入数据库指令文件 cd /usr/local/mysql/bin // 跳过权限认证 sudo ./mysqld_safe -- ...

  6. 解决CDH 访问权限问题

    CDH 6.2 安装好以后,直接使用root 或者 其他账号执行spark-shell 会报权限错误 22/01/04 17:46:28 ERROR spark.SparkContext: Error ...

  7. 邮箱的代理发送Send as权限不生效

     邮箱的代理发送Sendas权限不生效 最近,有需求为用户添加其它邮箱的代理发送Sendas权限.在Exchange的管理单元里添加完毕后,发现没有效果,客户端提示你没有权限以用户的名义发送邮件 ...

  8. 【Tool】Idea快捷键

    Windows Ctrl + F12: 查找当前类中的方法 Ctrl + N: 查找类 Ctrl + Alt + H: 查看方法调用关系 Ctrl + H: 查看类的继承关系 Alt + F7:查找类 ...

  9. Java内部类初探

    Java内部类初探 之前对内部类的概念不太清晰,在此对内部类与外部类之间的关系以及它们之间的调用方式进行一个总结. Java内部类一般可以分为以下三种: 成员内部类 静态内部类 匿名内部类 一.成员内 ...

  10. ES配置生成SSL使用的证书

    cd /usr/local/elasticsearch/bin/ ./elasticsearch-certgen ##################################### Pleas ...