JVM—对象的创建流程与内存分配
JVM—对象的创建流程与内存分配
创建流程
对象创建的流程图如下:

对象的内存分配方式
内存分配的方式有两种:
- 指针碰撞(Bump the Pointer)
- 空闲列表(Free List)
| 分配方式 | 说明 | 收集器 |
|---|---|---|
| 指针碰撞(Bump the Pointer) | 内存地址是连续的(新生代) | Serial和ParNew收集器 |
| 空闲列表(Free List) | 内存地址不连续(老年代) | CMS收集器和Mark-Sweep收集器 |


指针碰撞
指针碰撞示意图如下:

内存分配安全问题:
虚拟机给A线程分配内存的过程中,指针未修改,此时B线程同时使用了该内存,就会出现问题。
解决方式:
- CAS乐观锁:JVM虚拟机采用CAS失败重试的方式保证更新操作的原子性;
- TLAB (Thread Local Allocation Buffer)本地线程分配缓存,预分配。
分配主流程
首先从TLAB里面分配,如果分配不到,再使用CAS从堆里面划分。
对象如何进入老年代
对象进入老年代流程如下:

新对象大多数默认都进入Eden;
对象进入老年代的四种情况:
年龄太大 MinorGC15次【
-XX:MaxTenuringThreshold】;动态年龄判断:MinorGC后会动态判断年龄,将符合要求对象移入老年代;
MinorGC之后,发现Survivor区中的一批对象的总大小大于了这块Survivor区的50%,那么就会将此时大于等于这批对象年龄最大值的所有对象,直接进入老年代。
例子: Survivor区中有一批对象,年龄分别为年龄1+年龄2+年龄n的多个对象,对象总和大小超过了Survivor区域的50%,此时就会把年龄n及以上的对象都放入老年代。希望那些可能是长期存活的对象,尽早进入老年代。
比率可以由-XX:TargetsurvivorRatio指定
大对象直接进入老年代1M【
-XX:PretenureSizeThreshold】;(前提是Serial和ParNew收集器)为了避免大对象分配内存时的复制操作降低效率。
避免了Eden和Survivor区的复制。
MinorGC后存活对象太多无法放入Survivor。
空间担保机制
空间担保机制:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。此种机制我们称之为内存担保。
空间担保流程图如下:

对象内存布局
对象内存布局示意图如下:

对象里的三个区
堆内存中,一个对象在内存中存储的布局可以分为三块区域:
堆内存中,一个对象在内存中存储的布局可以分为三块区域:
对象头(Header) : Java对象头占8byte。如果是数组则占12byte。因为JVM里数组size需要使用4byte存储。
标记字段MarkWord:
用于存储对象自身的运行时数据,它是synchronized实现轻量级锁和偏向锁的关键。
默认存储:对象HashCode、GC分代年龄、锁状态等等信息。
为了节省空间,也会随着锁标志位的变化,存储数据发生变化。

类型指针KlassPoint:
- 是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
- 开启指针压缩存储空间4byte,不开启8byte。
- JDK1.6+默认开启
数组长度:如果对象是数组,则记录数组长度,占4个byte,如果对象不是数组则不存在。
对齐填充:保证数组的大小永远是8byte的整数倍。
实例数据(Instance Data):生成对象的时候,对象的非静态成员变量也会存入堆空间
对齐填充(Padding) :JVM内对象都采用8byte对齐,不够8byte的会自动补齐。
如何访问一个对象
有两种方式:
句柄:稳定,对象被移动只要修改句柄中的地址
直接指针:访问速度快,节省了一次指针定位的开销


JVM—对象的创建流程与内存分配的更多相关文章
- Java中对象创建时的内存分配
一.前言知识铺垫 1.逃逸对象:在一个方法内创建的对象没有被外界引用则称该对象为未逃逸的对象. 2.JDK1.6以后的HotSpot虚拟机支持运行时的对象逃逸分析. 3.JVM中的参数配置: 1) ...
- spring中容器和对象的创建流程
容器和对象的创建流程 1.先创建容器 2.加载配置文件,封装成BeanDefinition 3.调用执行BeanFactoryPostProcessor 准备工作: 准备BeanPostProcess ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
- 【JVM.2】垃圾收集器与内存分配策略
垃圾收集器需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 在前一节中介绍了java内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭:栈 ...
- 【Java杂货铺】JVM#Java高墙之GC与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾回收技术所围成的"高墙",墙外的人想进去,墙外的人想出来.--<深入理解Java虚拟机> 前言 上一章看了高墙的一半,接下 ...
- TObject简要说明-对象的创建流程
TObject = class //创建 constructor Create; //释放 procedure Free; //初始化实列 class functi ...
- JVM优化之垃圾收集器以及内存分配
在jvm中,实现了多种垃圾收集器,包括:串行垃圾收集器.并行垃圾收集器.CMS(并发)垃圾收集器.G1垃圾收集器,接下来,我们一个个的了解学习. 串行垃圾收集器 串行垃圾收集器,是指使用单线程进行垃圾 ...
- JVM学习十 -(复习)内存分配与回收策略
内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...
- JVM读书笔记之垃圾收集与内存分配
1 概述 说起垃圾收集( Garbage Collection , GC ) ,大部分人都把这项技术当做 Java 语言的伴生产物.事实上, GC 的历史远远比 Java 久远,1960 年诞生于 M ...
- Java对象(创建过程、内存布局、访问方法)
(Java 普通对象.不包括数组.Class 对象等.) 对象创建过程 类加载 遇到 new 指令时,获取对应的符号引用,并检查该符号引用代表的类是否已被初始化.如果没有就进行类加载. 分配内存 ...
随机推荐
- Jenkins共享库使用
简单使用 共享库(Shared libraries)是一种可以用来封装函数.变量甚至整个 Pipeline 的机制.通过共享库,可以将常用的功能和流程逻辑定义在单独的 Groovy 脚本中,然后在多个 ...
- 类型判断,代码块,流程控制及循环---day05
1.类型判断isinstance 用来做判断类型 语法: 用法一: isinstance(要判断的值,要判断的类型) 返回的是真或者假 用法二: isinstance(要判断的值,(可能的类型))如果 ...
- Gin框架入门
参考文档 Gin: https://gin-gonic.com/zh-cn/docs/quickstart/ net/http: https://pkg.go.dev/net/http 代码分析 pa ...
- java图书管理系统界面版本+mysql数据库
描述: java+mysql数据库实现的图书管理系统,实现了图书添加,图书删除,图书修改,图书查看,图书列表查看等,用户增加,用户删除.用户修改,用户查看等 功能: 图书管理功能:图书添加,图书删除, ...
- Java 通过属性名称读取或者设置实体的属性值
原因 项目实战中有这个需求,数据库中配置对应的实体和属性名称,在代码中通过属性名称获取实体的对应的属性值. 解决方案 工具类,下面这个工具是辅助获取属性值 import com.alibaba.fas ...
- 【Azure App Service for Linux】NodeJS镜像应用启动失败,遇见 RangeError: Incorrect locale information provided
问题描述 在App Service For Linux 中,部署NodeJS应用,应用启动失败. 报错信息为: 2023-08-29T11:21:36.329731566Z RangeError: I ...
- VC+MFC button获取+list复制+获取+页面转换+登录与数据库账户,密码进行对比 +基础知识
1 // DlgExec.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 5 #include "Self.h" 6 #incl ...
- 16 Educational Codeforces Round 142 (Rated for Div. 2)C. Min Max Sort(递归、思维、dp)
C. Min Max Sort 很不错的一道题目,不过脑电波和出题人每对上,\(qwq.\) 正难则反. 我们考虑最后一步是怎么操作的. 最后一步一定是对\(1\)和\(n\)进行操作 那么上一步呢? ...
- 单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有
单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有 develop 发展 开发 de = down 下面 velop 这里 vel 就是 lev的反写 op = ...
- 移远4G数传模块EC800M开发总结之基本备忘
一 前记 1 EC800M模块是移远推出的小尺寸低功耗针对可穿戴市场的数传产品.笔者在几个产品上使用过程中,遇到了一些问题. 这里做个备忘吧. 二 梳理 1 工具,这个串口的默认波特率为115200. ...