JVM对象创建与内存回收机制

news2025/1/12 7:57:18

对象的创建过程有如下步骤:
在这里插入图片描述
1.类加载检查:
        虚拟机遇到一个new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过,如果没有,那么必须先执行相应的类加载过程
        new指令对应到语言层面上讲是,new关键词、对象克隆、对象序列化等。
2.分配内存
        对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。这个步骤有两个问题:

  1. 如何划分内存
  2. 在并发情况下,可能出现在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。
    划分内存的方法:
            “指针碰撞”(默认)(Bump the Pointer):
            如果Java堆中的内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是吧那个指针向空闲空间那边挪动一段与对象大小相等的距离。
            “空闲类表”(Free List)
            如果Java堆中的内存并不是规整的,已使用的内存和空闲内存相互交错,那就没有办法简单的进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存快是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录
            解决并发问题的方法:
            1.CAS(Compare and swap)
            虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来分配内存空间的动作进行同步处理。
            2.本地线程分配缓冲(Thread Local Allocation Bufffer, TLAB)
            把内存分配的动作按照线程划分在不同的空间中进行,即每个线程在Java堆中预先分配一小块内存。通过-XX:+/-UseTLAB参数来设定迅即是否使用TLAB(JVM会默认开启-XX:+UseTLAB),- XX:TLABSize指定TLAB大小。

3.初始化
        内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
4.设置对象头
        对象除了成员变量之外,还有对象头,对象填充,对象在内存中存储的布局可以分为3块区域:对象头、实例数据和对齐填充
        1.Mark Word标记字段(32位占4字节,64位占8字节)自身运行时数据哈希表,GC分代年龄,锁状态标志,线程执有锁,偏向线程ID,偏向时间戳。
        2.Klass Pointer类型指针(开启压缩4字节,关闭压缩8字节)。剋的元数据指针(D。代码放在方法区,JVM使用Java头的类型指针拿到方法区的头。
        3.数组长度(4字节,只有数组对象才有)
5.执行(init)方法
        给对象真正的赋值以及执行构造方法。
对象大小与指针压缩
        启用指针压缩-XX:+UseCompressedOops(默认开启),禁止-XX:-UseCompressedOops
压缩对象地址到32位
为什么要进行指针压缩?

  1. 在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大带宽,同时GC也会承受较大压力。
  2. 为了减少64位平台下内存的消耗,启用指针压缩功能。
  3. 在JVM中,32位地址最大支持4G内存,可以通过对象指针的压缩编码、解码方式进行优化,使得JVM只用32位地址就可以支持更大的内存配置(小于等于32G)
  4. 堆内存小于4G时,不需要启用指针压缩,JVM会直接去除高32位地址,即使用低虚拟地址空间
  5. 堆内存大于32G时,压缩指针会失效,会强制使用64位堆Java对象寻址,这样会现1的问题,所以堆内存不要大于32G为好。

        -XX:+UseCompressedClassPointers默认开启的,只压缩对象头里的类型指针Klass Pointer对象内存分配。
        对象逃逸分析:比如User对象在方法执行后返回,则这个对象逃逸了,减少GC压力。
        -XX:DoEscopeAnalysis开启逃逸分析参数,JDK7后默认开启
        标量替换:一个对象如果经过逃逸分析能够确定这个对象在栈上分配,这里会做一个优化,即便栈帧里没有一整块空间放对象,也能够通过其他方法存在栈帧上。
        如果对象不逃逸,栈帧只放对象成员变量,把完整的对象打散放到栈帧上去,这几个变量都标识属于某一个对象。
        标量与聚合量:标量即不可以被进一步分解的量,而Java的基本数据类型就是标量,标量的对立就是可以被进一步分解的量,而这种量称为聚合量。而Java对象就是可以被进一步分解的聚合量。
        开启标量替换-XX:+ECiminateAllocations,JDK7后默认开启
        -Xmx 15m -Xms 15m -XX:+DoEscapeAnslysis -XX:+printGC -XX:+ElininoteAllocations.大对象直接进入老年代
        -XX:PretenurefSizeThreshold=1000000 -XX:+UseSerialGC(支持大对象ParNew)。定义大对象配置,这个参数只在Serial和ParNew两个收集器下有效
        长期存活的对象将进入老年代。当它的年龄增加到一定程度,默认为15岁,CMS收集器默认为6岁,通过-XX:maxTennringThreshold设置对象动态年龄判断。
对象动态年龄判断:
        如果S区超过50%,进入老年代,例如Survivor区域里现在有一批对象年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时会把年龄n(含)以上的对象都放入老年代,这个规则其实是希望那些可能是长期存活的对象,尽早进入老年代,对象动态年龄判断机制一般是在minor gc之后触发。把年轻代设大点(-Xmn)
老年代空间分配担保机制
在这里插入图片描述软引用、弱引用和虚引用在GC时没空间时会被回收。
finalize()方法最终判定对象是否存活。
如果你的对象实现了finalize,这个对象会做标记,不会马上回收,第二次标记,清理掉前执行该方法,finalize只会自救一次。
如何判断一个类是无用的类,方法区主要回收的是无用的类,那么如何判断一个类时无用类呢?
类在方法区,该区要被回收满足该类的实例都被回收。
        加载类的Class Loader被回收了,自定义的类加载器是有可能需要回收,比如JSP类加载器。
该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1401648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【golang】Context超时控制与原理

Context 在Go语言圈子中流行着一句话: Never start a goroutine without knowing how it will stop。 翻译:如果你不知道协程如何退出,就不要使用它。 在创建协程时,我们可能还会再创建一些别的子协程,那么这些协程的…

【书籍】强化学习第二版(英文版电子版下载、github源码)-附copilot翻译的中英文目录...

Python代码:https://github.com/ShangtongZhang/reinforcement-learning-an-introduction 英文原版书籍下载:http://incompleteideas.net/book/the-book-2nd.html 作者: 理查德S萨顿是阿尔伯塔大学计算机科学教授和强化学习与人工智能 AITF 主…

1.6万字全面掌握 BERT:自然语言处理(NLP)从初学到高级的全面指南

BERT(双向编码器表示来自Transformer的模型)是由Google开发的一种革命性的自然语言处理(NLP)模型。它改变了语言理解任务的格局,使机器能够理解语言中的上下文和细微差异。 在本博客中,我们将带您从 BERT …

信息安全概述

信息安全:防止任何对数据进行未授权访问的措施,或者防止造成信息有意无意泄漏、破坏、丢失等问题的发生,让数据处于远离危险、免于威胁的状态或特性。 网络安全:计算机网络环境下的信息安全。 信息安全现状及挑战 数字化时代威…

什么是VUE 创建第一个VUE实例

一、什么是Vue 概念:Vue (读音 /vjuː/,类似于 view) 是一套 构建用户界面 的 渐进式 框架 Vue2官网:Vue.js 1.什么是构建用户界面 基于数据渲染出用户可以看到的界面 2.什么是渐进式 所谓渐进式就是循序渐进,不一定非得把Vu…

Docker编译多平台文件、构建多平台镜像并运行

参考官方文档: Multi-stageMulti-platformMulti-platform images 文章目录 方法Buildx 设置使用QEMU仿真编译文件构建镜像 使用交叉编译(cross-compilation)编译文件构建镜像 在x86_64上运行arm64容器 方法 如果在 x86_64/amd64 的平台上&am…

Docker 操作之数据卷挂载【云原生】

文章目录 1. 镜像1.1 基本命令1.2 案例练习 2. 容器2.1 基本命令2.2 Nginx 案例2.3 Redis 案例 3. 数据卷3.1 基本命令3.2 Nginx 案例3.3 MySQL 案例 1. 镜像 镜像命令一般分两部分组成:repository:tag。比如 mysql:5.7,表示名称加版本。 在没有指定 t…

一文掌握Python所有常见的循环用法

更多资料获取 📚 个人网站:ipengtao.com 循环是编程中的重要概念,它允许我们重复执行一组操作,直到满足某个条件。Python提供了多种类型的循环,以适应不同的需求和场景。本文将详细介绍Python中所有常见的循环用法&am…

MySQL下对[表]的操作数据类型

目录 表的操作 创建表: 查看表结构: 修改表: 删除表: 数据类型 数据类型分类: 数值类型: tinyint类型越界测试: bit类型: 小数类型: 字符串类型: …

JAVA中 Lambda 方法引用 算法

算法和数据结构 一、Arrays类 接下来学习的类叫做Arrays,其实Arrays并不是重点,但是我们通过Arrays这个类的学习有助于我们理解下一个知识点Lambda的学习。所以我们这里先学习Arrays,再通过Arrays来学习Lamdba这样学习会更丝滑一些_. 1.1 …

【Qt Quick 项目(第一集Qt Quick UI 项目项目创建)】

# Qt Quick 项目 到底什么是Qt Qml、什么是Qt Quick、QtQuick应用程序与Qt Widget程序有何区别,为了让读者在学习QML之前有一个整体认识,这里先介绍几个Quick项目。 01 Qt Quick UI 项目

Java8的Stream最佳实践

从这一篇文章开始,我们会由浅入深,全面的学习stream API的最佳实践(结合我的使用经验),本想一篇写完,但写着写着发现需要写的内容太多了,所以分成一个系列慢慢来说。给大家分享我的经验的同时&a…

【博士每天一篇论文-技术综述】Machine Learning With Echo State Networks 一篇系统讲解ESN知识的五星文章

阅读时间:2023-11-21 1 介绍 年份:2020 作者:徐元超,曼尼托巴大学 期刊: 无 引用量:无 这篇文章是一篇技术报告,从递归神经网络(RNNs)引入到回声状态网络(…

JavaScript基础之JavaScript简介(什么是JavaScript?)

JavaScript简介 JavaScript,通常被缩写为JS,是一种轻量级、跨平台、单线程、解释编译的编程语言。它也被称为网页脚本语言。它以网页开发而闻名,许多非浏览器环境也使用它。 JavaScript是一种弱类型语言。JavaScript可用于客户端开发以及服…

shell编程学习

shell编程学习 变量的高级用法变量替换字符串处理获取字符索引获取子串长度抽取字符串中的子串 案例测试 变量的高级用法 变量替换 ##变量替换(贪婪,从前往后匹配,匹配到进行删除) test1I love you,you love me echo $test1 han…

Java研学-spring框架(一)

一 概述 1 介绍 Spring框架是一个开源的Java EE应用程序框架,旨在简化Java企业级应用的开发难度和开发周期,主要通过控制反转(IoC)和面向切面编程(AOP)等技术实现。   容器(Container&#x…

【CVE-2022-22733漏洞复现】

Apache ShardingSphere ElasticJob-UI漏洞 漏洞编号:CVE-2022-22733 文档说明 本文作者:SwBack 创作时间:2024/1/21 19:19:19 知乎:https://www.zhihu.com/people/back-88-87 CSDN:https://blog.csdn.net/qq_30817059 百度搜索: SwBack漏洞描述 Apache ShardingSphere Elast…

Python基础第二篇(Python基础语法)

文章目录 一、字面量二、注释三、变量四、数据类型五、数据类型转换六、标识符七、运算符八、字符串扩展内容(1)字符串定义(2)字符串拼接、(3)字符串格式化(4)字符串格式化的精度控制…

上位机图像处理和嵌入式模块部署(开篇)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 图像处理是现实生活当中很实用的一门技术。工业上一般采用的是机器视觉,以传统算法和光源控制为主,部分采用了深度学习技术…

MySQL的下载、安装、配置、登录,配置(图+文)(超级详细)

一、 软件的下载 1. 下载地址 官网: https://www.mysql.com 2. 打开官网,点击 DOWNLOADS 然后,点击 MySQL Community(GPL) Downloads 3. 点击 MySQL Community Server 4. 在 General Availability(GA) Releases 中选择适合的版本 …