jvm之自动内存管理
一、运行时数据区

程序计数器(线程私有)
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之自动内存管理的更多相关文章
- JVM介绍&自动内存管理机制
1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...
- 深入理解JVM(一) -- 自动内存管理机制
Java运行时数据区域分为:程序计数器,虚拟机栈,本地方法栈,Java堆,方法区,运行时常量池,直接内存,结构如下: 1.程序计数器: 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示 ...
- JVM探索之——内存管理(一)
本系列的第一篇文章,预计本系列最后面会有两三个案例. Java与C.C++不一样Java不需要Coder进行手动内存管理,而这一切都交给JVM进行自动内存管理,这从某种程度上来说也减轻了我们Coder ...
- JVM自动内存管理学习笔记
对于使用 C.C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任.对于 Java 程 ...
- JVM自动内存管理-Java内存区域与内存溢出异常
摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
- JVM自动内存管理机制——Java内存区域(上)
一.JVM运行时数据区域概述 Java相比较于C/C++的一个特点就是,在虚拟机自动内存管理机制的帮助下,我们不需要为每一个操作都写像C/C++一样的delete/free代码,所以也不容易出现内存泄 ...
- JVM自动内存管理机制--读这篇就GO了
之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...
- JVM | 第1部分:自动内存管理与性能调优《深入理解 Java 虚拟机》
目录 前言 1. 自动内存管理 1.1 JVM运行时数据区 1.2 Java 内存结构 1.3 HotSpot 虚拟机创建对象 1.4 HotSpot 虚拟机的对象内存布局 1.5 访问对象 2. 垃 ...
随机推荐
- 【ajax】发送请求 —— 结合【express】框架 { }
1.先用 express 框架搭建一个简单的服务器 (1)在文件夹上点击右键,点击"在集成终端中打开" (2)使用"npm i express"命令安装[exp ...
- 注解@DependsOn解析
作用 @DependsOn注解可以定义在类和方法上,意思是我这个组件要依赖于另一个组件,也就是说被依赖的组件会比该组件先注册到IOC容器中. 在哪里被解析 解析的地方在 ComponentScanAn ...
- 一文总结高并发大数据量下MySQL开发规范【军规】
在互联网公司中,MySQL是使用最多的数据库,那么在并发量大.数据量大的互联网业务中,如果高效的使用MySQL才能保证服务的稳定呢?根据本人多年运维管理经验的总结,梳理了一些核心的开发规范,希望能给大 ...
- MySQL数据备份 mysqldump 详解
MySQL数据备份流程 1 打开cmd窗口 通过命令进行数据备份与恢复: 需要在Windows的命令行窗口中进行: l 开始菜单,在运行中输入cmd回车: l 或者win+R,然后输入cmd回车,即可 ...
- Cat Theme
将博客皮肤设置为: SimpleMemory 插入CSS代码 #EntryTag{margin-top:20px;font-size:9pt;color:gray}.topicListFooter{t ...
- Python数据分析教程(一):Numpy
原文链接:https://blog.onefly.top/posts/13140.html 数据的纬度 一维数据:列表和集合类型 二维数据:列表类型 多维数据:列表类型 高维数据:字典类型或数据表示格 ...
- day02-代码实现01
多用户即时通讯系统02 4.编码实现01 4.1功能实现-用户登录 4.1.1功能说明 因为还没有学习数据库,我们人为规定 用户名/id = 100,密码为 123456 就可以登录,其他用户不能登录 ...
- 使用 febootstrap 制作自定义基础镜像
转载自:https://cloud.tencent.com/developer/article/1454524 文章目录1.febootstrap 介绍2.环境.软件准备3.febootstrap 安 ...
- 【C++】从零开始的CS:GO逆向分析2——配置GLFW+IMGUI环境并创建透明窗口
[C++]从零开始的CS:GO逆向分析2--配置GLFW+IMGUI环境并创建透明窗口 使用的环境:Visual Studio 2017,创建一个控制台程序作为工程文件 1.配置glfw 在git ...
- DML添加数据-删除数据-修改数据
DML添加数据 语法 insert into 表名(列名1,列名2,列名n) values(值1,值2,值n) 列:INSERT INTO day02(id,NAME,age) VALUES(1,&q ...