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

相关文章

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代