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. 垃 ...
随机推荐
- Windows权限维持总结
windows权限维持 注册服务 sc create 服务名 binpath= "cmd.exe /k 木马路径" start="auto" obj=" ...
- KingbaseES insert all/first 功能介绍
KingbaseES 内置了对于insert all / first 语法的支持. 一.数据准备 create table t1(product_id number, product_name var ...
- CURL 用法记录
CURL 用法记录 在工作中经常需要用到curl 命令,记录一下常用的场景 Send a POST Request with JSON Data curl -d '{"login" ...
- 发现tab换成空格不起作用,然后解决如下。
今天发现把 .vimrc 加了set expandtab之后不起作用,这个本来是把代码中的制表符换成空格,免得不同人的设置不同造成代码缩进混乱. 然后搞了半天搞不定,应该是加载了.vimrc之后又加了 ...
- 亚马逊云科技现身世界人工智能大会,揭示AI最新技术趋势
2022世界人工智能大会(WAIC)于日前落幕.经过过去四届的发展与沉淀,今天的世界人工智能大会已成为人工智能领域最有影响力的国际盛会之一,今年大咖云集.国际大厂扎堆,充分彰显了大会的国际影响力和磁力 ...
- 关于“No loop matching the specified signature and casting was found for ufunc lstsq_n”问题的解决
下面这段代码是使用MatPlotLib绘制数据随时间变化的趋势. import datetime as dt import numpy as np import pandas as pd import ...
- C语言大作业---学生信息管理系统
xxxx信息管理系统 简介 因为大作业规定的踩分项就那么多,为了不浪费时间 + 得分,就写成这样.现在看看,命名不规范,书写风格糟糕,全塞在一个源代码中······ 不过,应付大作业是没问题的 实验报 ...
- prometheus告警规则模板:MySQL,nginx,node
rules_up.yml groups: - name: up rules: - alert: mysql expr: up{instance="db1",job="my ...
- Docker Compose的安装及命令补全
安装Compose Compose的安装有多种方式,例如通过shell安装.通过pip安装.以及将compose作为容器安装等等.本文讲解通过shell安装的方式.其他安装方式如有兴趣,可以查看Doc ...
- Elasticsearch Dockerfile 例子
文章转载自:https://elasticstack.blog.csdn.net/article/details/111692444 前提条件 在继续执行本教程中概述的步骤之前,你需要具备一个关键的先 ...