第二十二期:New一个对象的时候发生了什么?

如你所知,Java是一门面向对象的编程语言。我们平常在写代码的时候也是在不停的操作各种对象,那么当你在写出User user = new User();这样一行代码的时候,JVM都做了些什么呢?

作者:湖人总冠军

 一、引言

如你所知,Java是一门面向对象的编程语言。我们平常在写代码的时候也是在不停的操作各种对象,那么当你在写出User user = new User();这样一行代码的时候,JVM都做了些什么呢?

二、了解对象

1、内存布局

在Hotspot虚拟机中一个对象的内存布局分为三个部分:对象头、实例数据、对齐填充。

  • 对象头又有两部分的信息,第一部分是用于存储对象自身的运行数据(HashCode、GC分代年龄、锁状态标志等)。另一部分是类型指针,指向它的类元数据,虚拟机通过这个指针确定这个对象是哪个类的实例(如果使用句柄池方式则不会有)。如果是数组还会有一个记录数组长度的如下表所示:

Mark Word是一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。各状态下的存储内容如下表所示:

  • 实例数据部分是真正存储的有效信息,就是在代码中定义的各种类型的字段内容。无论是父类继承下来的,还是在子类中的。
  • 对齐填充不是必须存在的,仅仅起着占位符的作用,因为HotSpot虚拟机要求对象的起始地址必须是8字节的整数倍。

2、对象的访问

Java程序中我们操作一个对象是通过指向这个对象的引用。我们都知道对象存在堆中,这个引用存在虚拟机栈中。那么引用通过什么方式去定位堆中对象的位置呢?

  • 直接指针法(HotSpot实现):引用中直接存储的就是堆中对象的地址。好处就是一次定位速度快,缺点是对象移动(GC时对象移动)引用本身需要修改。

  • 句柄法:Java堆中划分出一部分作为句柄池,引用存储的是对象的句柄地址,而句柄中包括了对象实例和类型的具体位置信息。好处是对象移动只会改变句柄中的实例数据指针,缺点是两次定位。

三、创建对象流程

上面介绍了对象的基本信息,现在来讲一讲创建对象的流程:

  1. 当虚拟机遇到一条new指令时,会去检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查代表的类是否已经被类加载器加载。如果没有被加载那么必须先执行这个类的加载。
  2. 类加载检查通过后,虚拟机将为新对象分配内存,对象所需内存的大小在类加载后便可以确定。
  3. 内存分配完成后,虚拟机需要将对象初始化为零值,保证对象的实例变量在代码中不赋初始值就能直接使用。类变量在类加载的准备阶段初始化为零值。
  4. 对对象头进行必要信息的设置,比如如何找到类的元数据信息、对象的HashCode、GC分代年龄等。
  5. 经过上述操作,一个新的对象已经产生,但是方法还没有执行,所有的字段都是零值。这时候需要执行方法(构造方法)把对象按照程序员的意愿进行初始化。类变量的初始化操作在类加载的初始化阶段方法完成

分配内存有两种方式:

  • Java堆内存是规整的(使用标记整理或带压缩的垃圾收集器),使用一个指针指向空闲位置,分配内存既将指针移动与分配大小相等的距离
  • 内存不是规整的(使用标记清除的垃圾收集器),虚拟机维护一个可用内存块列表,分配内存时从列表中找到一个足够大的内存空间划分给对象并更新可用内存列表。

无法找到足够的内存时会触发一次GC

分配内存时并发问题解决方案:

  • 对分配内存空间的动作进行同步操作---采用CAS失败重试的方式保证更新操作的原子性。
  • 每个线程在堆中预先分配一块小内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存就在它的TLAB上分配,只有TLAB用完并分配新的TLAB时才需要同步锁定。通过-XX:+/-UseTLAB参数来设定。

四、创建对象指令重排序问题

  1. A a = new A(); 

new一个对象的简单分解动作:

  1. 分配对象的内存空间
  2. 初始化对象
  3. 设置引用指向分配的内存地址

其中2、3两步间会发生指令重排序,导致多线程时如果在初始化之前访问对象则会出现问题,单例模式的双重检测锁模式正是会存在这个问题。可以使用volatile来禁止指令重排序解决问题

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期科技领域知识)

歌谣带你看java面试题

 

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

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

相关文章

【数据结构与算法】【算法思想】Dijkstra算法

图的两种搜索算法,深度优先搜素和广度优先搜索。这两种算法主要是针对无权图的搜索算法。针对有权图,也就是图中的每条边都有一个权重,该如何计算两点之间的最短路径?最短路径算法(Shortest Path Algorithm&#xff09…

第二十三期:程序员节Keep被曝突然裁员300多人,60%是开发和运营

社交健身App “Keep”突然裁员超300人,而且是在1024程序员节。此次被裁的人员中,大约有60%的人是开发和运营,补偿方案为N1。 作者:三言财经 10月24日脉脉有多条消息称,社交健身App “Keep”突然裁员超300人&#xff0…

542. 01 Matrix

输入:元素值为0或者1的矩阵。 输出: 每个元素距离0的最近距离是多少。 规则:相邻单元格的距离是1,相邻是指上下左右4个方向。 分析:这类似于学习课程安排,可以从元素值为0的单元开始沿4个方向遍历。matrix[…

第二十四期:管理 | 成功领导远程IT团队的7个技巧

管理虚拟工作环境需要各种真实世界的技能和工具。以下是激发创造力和生产力的策略。为了在日益缺乏人才和竞争激烈的IT世界中取得成功,越来越多的企业开始依赖于地理上分散的劳动力。 作者:John Edwards 管理虚拟工作环境需要各种真实世界的技能和工具…

310. Minimum Height Trees

输入:包含n个节点的无向图。n:表示从0到n-1,n个节点。edges:int数组,是从一个节点到另外一个节点。但是没有方向。 输出:以哪些节点为根节点,具有最小高度的树,返回这些根节点。 规则…

计算获取最小值和最大值

比如,在下面的销售业绩中,统计业务员的销售业绩中最大值和最小值。 下面是业务数据: CREATE TABLE [dbo].[SalesPerformance]([ID] [int] IDENTITY(1,1) NOT NULL,[Salesman] NVARCHAR(30) NOT NULL,[OrderDate] [DATE] NULL,[Sell] DECIM…

第二十五期:知乎用Go替代Python,说明了啥

众所周知,知乎早在几年前就将推荐系统从 Python 转为了 Go。于是乎,一部分人就说 Go 比 Python 好,Go 和 Python 两大社区的相关开发人员为此也争论过不少,似乎,谁也没完全说服谁。 作者:hello架构 大概每…

[Leetcode][第106题][JAVA][ 从中序与后序遍历序列构造二叉树][分治][递归]

【问题描述】[中等] 【解答思路】 public class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {int inLen inorder.length;int postLen postorder.length;// 特判if (inLen ! postLen) {throw new RuntimeException("输入错误");}return …

第二十六期:英国建设下一代IOT基础设施的历史机遇和挑战

无论未来物联网发展的中心在哪里,都会带来一笔巨大的财富。但许多地区面临的真正障碍是缺乏可用的光纤基础设施来形成回程网络。接下来看一看全光纤在英国的推广情况。 作者:风车云马编译 世界各地的市政当局都在呼吁制定支持5G的基础设施计划。这些基…

[Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]

【问题描述】[中等] 【解答思路】 copyOfRange class Solution {public TreeNode constructFromPrePost(int[] pre, int[] post) {if(prenull || pre.length0) {return null;}return dfs(pre,post);}private TreeNode dfs(int[] pre,int[] post) {if(prenull || pre.length0)…

第二十七期:Deepfake视频正在快速传播,也许区块链能够阻止这波“瘟疫”

“假新闻”一词已经成为当下的热门话题,而Deepfake(即看似真实,但实为伪造的视频操纵行为)则会进一步加剧民众与媒体之间的不信任危机。 作者:佚名来源 “假新闻”一词已经成为当下的热门话题,而Deepfake(即看似真实,…

POJ 1276 完全背包

Sample Input 735 3 4 125 6 5 3 350 633 4 500 30 6 100 1 5 0 1 735 0 0 3 10 100 10 50 10 10 Sample Output 735 630 0 0题意:你的银行卡里有 cash 元,而ATM机里有 n 种面值的钱,n行每种钱的数量和面值。  问 最多能从这台AT…

[Leetcode][第117题][JAVA][填充每个节点的下一个右侧节点指针][BFS]

【问题描述】[中等] 【解答思路】 1. 层次遍历 public Node connect(Node root) {if (root null)return root;Queue<Node> queue new LinkedList<>();queue.add(root);while (!queue.isEmpty()) {//每一层的数量int levelCount queue.size();//前一个节点Node …

第二十八期:Java线程池的四种用法与使用场景

线程池的作用主要是为了提升系统的性能以及使用率。文章刚开始就提到&#xff0c;如果我们使用最简单的方式创建线程&#xff0c;如果用户量比较大&#xff0c;那么就会产生很多创建和销毁线程的动作&#xff0c;这会导致服务器在创建和销毁线程上消耗的性能可能要比处理实际业…

php连接mysql遇到的问题: (HY000/1130) 和 [caching_sha2_password]

说明一下我的mysql是安装在虚拟机上的 所以遇到的第一个问题就是访问问题 解决&#xff1a; update user set host % where user root; 重启mysql服务 试了很多方法&#xff0c;也找了很多方法只有这个可行。 问题2&#xff0c; 解决&#xff1a; https://www.cnblogs.com/un…

847. Shortest Path Visiting All Nodes(一)

输入&#xff1a;一个无向图&#xff0c;各个节点的标签是0、1、2…N-1。graph[i][j]表示从节点i到节点j有一条边。 输出&#xff1a;返回每个节点都访问一遍需要的最少步骤。 规则&#xff1a;各个节点可以重复访问。 分析&#xff1a;  如果可以知道从每个节点开始&#xf…

第二十九期:程序员们该如何破局!

我是实打实的程序员一枚&#xff0c;身为一个过来人&#xff0c;我觉得有必要说几点针对程序员们的破局思维&#xff0c;希望能解决不少人的迷茫与困惑。 作者&#xff1a;stormzhang 新读者可能不知道&#xff0c;老读者都晓得&#xff0c;虽说现在转身做了自媒体&#xff0c…

[Leetcode][第75题][JAVA][颜色分类][双(三)指针][计数排序]

【问题描述】[中等] 【解答思路】 1. 三指针 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(1) class Solution {public void sortColors(int[] nums) {int n nums.length;int p0 0, p2 n - 1;for (int i 0; i < p2; i) {while (i < p2 && nums[i] …

第三十期:程序员报告:男性占比超87% 北京月薪12184元最高

1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%。 作者&#xff1a;朝晖 1024“程序员节”&#xff0c;58同城招聘研究院发布程序员行业大数据报告显示&#xff0c;程序员男性占比高达87.29%&#xff0c;北…

[Leetcode][LCP 19][JAVA][秋叶收藏集][动态规划]

【问题描述】[中等] 【解答思路】 1. 动态规划 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public int minimumOperations(String leaves) {if (leaves null || leaves "") { // 排除 不合法参数情况return 0;}int length leave…