博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java内存布局
阅读量:4045 次
发布时间:2019-05-24

本文共 1129 字,大约阅读时间需要 3 分钟。

内存布局

各位兄弟们,应该都清楚,我们创建的对象都是被存放到堆中的,最后我们获得到的是一个对象的引用指针。那么有一个问题就会诞生了, JVM 创建的对象的时候,开辟了一块空间,那这个空间里都有什么东西?这个就是我们这个点的内容。

先来结论:** Java 中存在两种类型的对象,一种是普通对象,另一种是数组**

对象内存布局

我们来一个一个解释其含义。

**白话版: **对象头中包含又两个字段, Mark Word 主要存储改对象的锁信息, GC 信息等等(锁升级的实现)。而其中的 Klass Point 代表的是一个类指针,它指向了方法区中类的定义和结构信息。而 Instance Data 代表的就是类的成员变量。在我们刚刚学习 Java 基础的时候,都听过老师讲过,对象的非静态成员属性都会被存放在堆中,这个就是对象的 Instance Data 。相对于对象而言,数组额外添加了一个数组长度的属性

最后一个对其数据是什么?

我们拿一个场景来展示这个原因: **想像一下,你和女朋友周末打算出去玩,女朋友让你给她带上口红,那么这个时候你仅仅会带上口红嘛?当然不是,而是将所有的必用品统统带上,以防刚一出门就得回家拿东西!!! **这种行为叫啥? **未雨绸缪,没错,暖男行为 **。还不懂?再来一个案例。 **你准备创业了,资金非常充足,你需要注册一个域名,你仅仅注册一个嘛?不,而是将所有相关的都注册了,防止以后大价钱买域名 **。一个道理。

而对于 CPU 而言,它在进行计算处理数据的时候,不可能需要什么拿什么吧,那对其性能损耗非常严重。所以有一个协议,** CPU 在读取数据的时候,不仅仅只拿需要的数据,而是获取一行的数据,这就是缓存行,而一行是64个字节**。

所以呢?通过这个特性可以玩一些诡异的花样,比如下面的代码。

publicclassCacheLine{privatevolatileLong l1 , l2;}

 

我们给一个场景:两个线程 t1和t2 分别操作 l1l2 ,那么当 t1l1 做了修改以后, l2 需不需要重新读取主内存种值。答案是一定,根据我们上面对于缓存行的理解, l1和l2 必然位于同一个缓存行中,根据缓存一致性协议,当数据被修改以后,其他 CPU 需要重新重主内存中读取数据。 这就引发了伪共享的问题

那么为什么对象头要求会存在一个对其数据呢?

HotSpot 虚拟机要求每一个对象的内存大小必须保证为8字节的整数倍,所以对于不是8字节的进行了对其补充。其原因也是因为缓存行的原因

对象=对象头+实例数据

原文:https://www.jianshu.com/p/503df66fee3e
 

转载地址:http://atwci.baihongyu.com/

你可能感兴趣的文章
机器学习实战之决策树(一)
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[LeetCode By Python]121. Best Time to Buy and Sell Stock
查看>>
[LeetCode By Python]122. Best Time to Buy and Sell Stock II
查看>>
[LeetCode By Python]125. Valid Palindrome
查看>>
[LeetCode By Python]136. Single Number
查看>>
Android/Linux 内存监视
查看>>
用find命令查找最近修改过的文件
查看>>
Android2.1消息应用(Messaging)源码学习笔记
查看>>
android raw读取超过1M文件的方法
查看>>
ubuntu下SVN服务器安装配置
查看>>
MPMoviePlayerViewController和MPMoviePlayerController的使用
查看>>
CocoaPods实践之制作篇
查看>>
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>
iphone开发之SDK研究(待续)
查看>>