JVM12_StringTable、对象的实例化、对象的内存布局 、对象访问的两种方式、对象头信息

本文主要是介绍JVM12_StringTable、对象的实例化、对象的内存布局 、对象访问的两种方式、对象头信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

字符串常量池

为什么要调整,从永久代放到堆空间?

其实就是因为字符串常量池在永久代中,回收效率不高,而开发中会产生大量的字符串,这样就会导致永久代内存不足。放在堆中,能及时回收内存
在这里插入图片描述

静态变量

首先,new出来的东西没有疑问,都是放到对空间中的,
JDK中静态变量的变化,只是指的静态变量的引用存放的位置,JDK6是在永久代,JDK7和8放到了堆空间中

jhsdb.exe是在JDK9时才出现的,监控进程的工具
在这里插入图片描述
静态变量和映射的Class对象都放在了堆中

方法区的垃圾回收行为

对于方法区的回收行为,记住两点:
1、java虚拟机规范,对方法区的垃圾回收要求不高,可以不进行回收
2、如果要回收垃圾,主要是两方面:常量池中废弃的常量和不再使用的类,常量的回收简单,但是对于类的回收则不太容易
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述
面试题
在这里插入图片描述
在这里插入图片描述

对象的实例化

在这里插入图片描述
在这里插入图片描述

创建对象的方式

在这里插入图片描述

1、new,除了简单的new , 还有变形:单例模式,XxxFactory的静态方法

2、3、反射方式:Class下的newInstance()方式在JDK9开始不推荐使用了,因为要求高,必须是空参的构造器才可以
现在推荐使用Constructor下的newInstance(Xxx)的方式。可以调用无参的或者带参的构造器方式,比较灵活

4、使用clone() 浅复制
5、反序列化。序列化可以实现数据从一个进程到另一个进程的传递,基于本地和网络都可以实现,将对象转化成二进制流,传递后再从二进制流转换成对象
6、第三方库:

创建对象的步骤

在这里插入图片描述

首先,new关键字,调用的是底层的new方法创建对象
先查看在方法区是否加载了Object类, 加载完后就开始在堆中开辟对象需要的空间,
1、加载当前对象创建所需要的类对象
在这里插入图片描述
如果是引用变量,那么只给4个字节大小
当内存规整的时候,为对象分配内存使用指针碰撞法,即规整地新分配内存,此处GC对应标记压缩算法。
当内存不规整时,为对象分配内存时会维护一个列表,专门存放空闲内存位置。当分配内存时选择可以放下的内存进行分配
此处GC对应标记清除算法,如CMS,垃圾回收后内存就不是规整的。
在这里插入图片描述

在这里插入图片描述
第四步,这里给对象属性赋值的操作是:属性的默认初始化。
对象属性赋值操作有
1、属性的默认初始化
2、显示初始化和代码块中初始化,这两个就看代码的前后位置
3、构造器中初始化
在这里插入图片描述
第六步:对属性进行显式初始化,代码块初始化、构造器中初始化,也就是Person()这一步,在解析后的字节码中就是中的内容
总结六步:1、加载类元信息2、为对象分配内存空间,分内存规整和不规整的不同分配方式
3、处理并发问题4、为属性进行默认零值初始化5、设置对象头信息
6、最终属性显式初始化、代码块中初始化、构造器中初始化
这六步执行完后,完整的对象才算创建完成

对象的内存布局

在这里插入图片描述
对象头包含两部分内容:运行时元数据和类型指针,运行时元数据其实就是运行中的一些必要信息,类型指针就是对象是由哪个类创建的

对象创建的示例说明

在这里插入图片描述
在这里插入图片描述

通过上图代码创建Customer()对象的过程,内存中布局如下:
在这里插入图片描述

对象访问定位

在这里插入图片描述
通过栈帧中的对象引用来访问堆中创建好的对象,引用保存了对象存储位置的内存地址,所以可以访问到这个对象实例

对象访问的两种方式

由于java虚拟机规范中并没有明确对象访问采用哪种方式,所以就存在这么两种方式
Hotspot采用的是直接指针的方式

1、句柄访问

在这里插入图片描述

2、直接指针

在这里插入图片描述
之所以hotspot最终采用的是直接指针的对象访问方式,还是因为优势更大一点,
在直接指针访问中,1、不存在句柄池这个中间量,所以不用给其分配内存,节省空间,
2、没有中间句柄池,直接进行访问,效率更高
当然,直接指针的缺点就是当对象存储位置发生修改时,变量引用也需要修改,
而在句柄访问方式中,对象存储位置变化时,只要修改句柄池中指针的位置即可。

这篇关于JVM12_StringTable、对象的实例化、对象的内存布局 、对象访问的两种方式、对象头信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888180

相关文章

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

python中的显式声明类型参数使用方式

《python中的显式声明类型参数使用方式》文章探讨了Python3.10+版本中类型注解的使用,指出FastAPI官方示例强调显式声明参数类型,通过|操作符替代Union/Optional,可提升代... 目录背景python函数显式声明的类型汇总基本类型集合类型Optional and Union(py

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定