「每日五分钟,玩转JVM」:对象从哪来
面向对象
众所周知,Java是一门面向对象的高级编程语言,那么现在问题来了,对象从哪来呢?有些人会说通过new关键字来创建一个对象,说的很好,本篇我们就来解密在new一个对象的过程中,JVM都给我们做了什么工作。
走哪来,到哪去
一个对象的诞生必定有一个类,通常我们都是通过new关键字实例化一个类来获取该类的一个对象,类在加载的过程中会经历一系列的检查,解析,初始化等一系列的过程,我们会在后面详细的分步骤进行讲解,这里我们只关心对象。
下面对象就要被加载到我们的虚拟机内存的堆内存中,加载到堆内存中也就意味着这个对象需要一定的空间,那么这个空间走哪来呢?这里JVM规范给出了两种情况:
指针碰撞
所谓指针碰撞,前提的条件是JVM的堆内存是绝对工整的,中间有一个指针作为分割空闲空间和已用空间的”三八线“,指针碰撞一般发生在Eden区,跟踪在Eden创建的最后一个对象,这个对象会被放在Eden的顶部。如果有足够的空间,对象就会被创建在Eden,并且被放置在顶部,然后将指针向上移动(如果你玩过俄罗斯方块,你就应该明白,说白了就是一种不可消除绝对规整的俄罗斯方块),当俄罗斯方块被堆满之后,就会触发一次Minor GC(关于GC的知识,我们在后面来讲解)
打个比方来说,一个班里有很多座位,学生必须按照顺序来坐,这样只需要知道最后一个进来的学生坐哪就知道下一个学生坐哪,以及有没有空位~
在单线程的情况下,我们这样使用是没有什么问题的,但是如果处于多线程并发的情况,就会出现分配空间失败的情况,打个比方来说,就是把一个位置同时卖给了两个人,这种情况势必就会打架,这种情况下,我们可以采取两种方法来解决这个问题:
- 使用CAS+失败重试保证更新操作的原子性
CAS(Compare And Swap),关键是3个操作数。
内存值V
旧的预期值A
要修改的新值B
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
第二种方法,结合我们上节课说到的TLAB来实现,在分配内存的时候在每个线程上的TLAB(Thread Local Allocation Buffer)区域进行分配,这里分配的时候可以初始化为零值,这一步操作保证了对象实例字段在Java代码中不赋值就可以直接使用。
Free List
另一种情况是当堆内存不规整的情况下(学生不要排排坐),JVM会把没来上课的学生(未使用的内存)记到小本本上,当有新学生(新的对象)来上课的时候,可以去看本本上的座位图给学生安排座位~
这个JVM的小本本就叫做空闲列表(Free List)。
结语
到这里,对于虚拟机,对象就已经找到了自己的座位并落座,下一篇,我们来介绍一下对象中都有什么。
公众号
「每日五分钟,玩转JVM」:对象从哪来的更多相关文章
- 「每日五分钟,玩转JVM」:线程共享区
前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计 ...
- 「每日五分钟,玩转JVM」:对象内存布局
概览 一个对象根据不同情况可以被划分成两种情况,当对象是一个非数组对象的时候,对象头,实例数据,对齐填充在内存中三分天下,而数组对象中在对象头中多了一个用于描述数组对象长度的部分 对象头 对象头分为两 ...
- 「每日五分钟,玩转JVM」:线程独占区
前言 如果我们对计算机组成有所了解,那么我们一定会知道在计算机中有一块儿特殊的区域,称之为寄存器,寄存器包括了指令寄存器和程序计数器,这两样位于CPU中,作为程序运行的大脑来控制程序的运行和流转. 而 ...
- 「每日五分钟,玩转 JVM」:GC 概览
前言 GC(Garbage Collection)是我们在学习 JVM 的过程中不可避免的一道坎,接下来,我们就来系统的学习一下 GC. 做一件事情之前,我们一定要去知道我们为什么要去做,这里不仅仅指 ...
- 「每日五分钟,玩转JVM」:指针压缩
64位JVM和32位JVM 最初的时候,JVM是32位的,但是随着64位系统的兴起,JVM也迎来了从32位到64位的转换,32位的JVM对比64位的内存容量比较有限,但是我们使用64位虚拟机的同时,也 ...
- 「每日五分钟,玩转JVM」:两种算法
前言 上篇文章,我们了解了GC 的相关概念,这篇文章我们通过两个算法来了解如何去确定堆中的对象实例哪些是我们需要去回收的垃圾对象. 引用计数算法 引用计数法的原理很简单,就是在对象中维护一个计数器,当 ...
- zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》
本篇文章阅读时间5分钟左右 点击看<每日五分钟搞定大数据>完整思维导图 zookeeper作为一个分布式协调系统,很多组件都会依赖它,那么此时它的可用性就非常重要了,那么保证可用性的同 ...
- zookeeper核心-zab协议-《每日五分钟搞定大数据》
上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...
- HDFS-异常大全-《每日五分钟搞定大数据》
点击看<每日五分钟搞定大数据>完整思维导图以及所有文章目录 问题1:Decomminssioning退役datanode(即删除节点) 1.配置exclude: <name>d ...
随机推荐
- 从flink-example分析flink组件(3)WordCount 流式实战及源码分析
前面介绍了批量处理的WorkCount是如何执行的 <从flink-example分析flink组件(1)WordCount batch实战及源码分析> <从flink-exampl ...
- 【TensorFlow 2】矩阵基础
placeholder placeholder为tf中的占位符,用来保存数据.语法为: tf.placeholder(dtype, shape=None, name=None) dtype:数据类型 ...
- PyCharm 配置 Git 教程
之前给大家介绍了 Git 安装及使用指南,今天再给大家介绍一下在 PyCharm 中使用 Git. 1 打开 File -> Settings -> Version Control -&g ...
- RobotFramework_2.新建项目、新建用例、运行用例和查看测试报告
RobotFramework的使用 新建一个项目 Robotframework-ride的界面 分了四个区域:菜单栏.工具栏.案例及资源区.工作区,如下图: 创建项目 首先,点击File-New Pr ...
- 深入理解HashMap(jdk7)
HashMap的结构图示 jdk1.7的HashMap采用数组+单链表实现,尽管定义了hash函数来避免冲突,但因为数组长度有限,还是会出现两个不同的Key经过计算后在数组中的位置一样,1.7版本 ...
- 【iOS】沙盒目录
有关沙盒目录参考: http://blog.csdn.net/totogo2010/article/details/7669837 获取沙盒路径,参考代码: NSArray *paths = NSSe ...
- 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术
这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...
- 线上调试bug
在以往的工作中,线上一有bug,就需要把文件弄到本地来改,但经常会碰见本地环境又和线上不一样,导致调试困难,闭着眼睛改好之后传到线上去看对不对,不对的话又要改,循环往复,要多麻烦就有多麻烦啊. 今天给 ...
- Spring 核心技术(5)
接上篇:Spring 核心技术(4) version 5.1.8.RELEASE 1.4.5 自动装配协作者 Spring 容器可以自动连接协作 bean 之间的关系.你可以让 Spring 通过检查 ...
- 基于Spring注解的上下文初始化过程源码解析(二)
上一篇看完了register方法的代码,继续跟后面代码 后面执行refresh方法,代码清单如下: public void refresh() throws BeansException, Illeg ...