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. 垃 ...
随机推荐
- 【Java】学习路径48-线程锁ReentrantLock
与上一章学习的线程锁synchronized类似,都是为了解决线程安全的问题. 使用方法: 新建一个ReentrantLock对象.(如果使用Thread多线程,则需要声明static静态) 然后在需 ...
- 字节一面:说说TCP的三次握手
上周有朋友去了字节面试,问到了TCP三次握手的问题,当时回答的不是很好,对于三次握手的发送的报文信息都不太熟,本文主要做一下总结和记录. TCP全称为Transmission Control Prot ...
- Qt 创建按钮动画
1 封装自定义按钮 myPushBttton 2 构造函数 (默认图片,按下后显示图片) 3 测试开始按钮 4 开始制作特效 5 zoom1 向下弹跳 6 zoom2 向上弹跳 代码如下 main.h ...
- SpringMVC前置复习以及扩展
SpringMVC ssm:mybatis+Spring+SpringMVC javaSE javaweb 框架 理解的DAO层和Service层 先简单来讲下Dao层,和Service层的概念: S ...
- KingbaseES 创建只读(read_only)用户
数据库版本: prod=> select version(); version --------------------------------------------------------- ...
- Spring Boot2配置Swagger2生成API接口文档
一.Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 及时性 (接 ...
- [Python]-opencv-python模块(cv2)-图片读取和格式转换
python常常用opencv模块来处理图像. import cv2 as cv 读取图片:imread() 默认按照彩色三通道读取: img = cv2.imread(path) 读取灰度图: im ...
- AVL Tree (1) - Definition, find and Rotation
1. 定义 (15-1) [AVL tree]: 一棵空二叉树是 AVL tree; 若 T 是一棵非空二叉树, 则 T 满足以下两个条件时, T 是一棵 AVL tree: T_LeftSubtre ...
- 2.Python环境搭建
Python是一个跨平台.可移植的编程语言,因此可在windows.linux/unix和Mac os x系统中安装使用.安装完成后,你会得到Python解释器环境,一个命令行交互环境,一个简单的集成 ...
- 8.第七篇 验证kube-apiserver及kubeconfig配置详解
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483818&idx=1&sn=7572b791 ...