Java对象在虚拟机中的创建、内存分布、访问定位以及死亡判定
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6535156.html
一:虚拟机中对象的创建
1:虚拟机遇到new指令时,在常量池检索是否有对应的符号引用,对应的类是否已加载、解析和初始化。没有则先加载对应的类文件到虚拟机。
2:加载类文件后,为新对象分配内存(内存大小在加载类后即可确定):有两种办法,取决于当前区域内存的情况
1)指针碰撞法:若内存是连续的,空闲内存和占用内存中间有一指针作为分界点,则分配内存时只需把指针往空闲区域移动相应大小即可;
2)空闲列表法:若内存中占用空间和空闲空间交错存在,则虚拟机维护一个表格记录各个空闲的块,在分配时从列表中找到足够大的空闲块并更新表格即可。
在多线程下为对象分配内存:把内存分配动作划分在不同的空间进行,每个线程在Java堆预先分配一小块内存作为自己的本地线程分配缓冲区(TLAB),之后哪个线程需要分配内存则在自己的TLAB中分配即可,用完了才需要在共享的堆中进行分配。而在共享的堆空间分配时,使用同步锁进行限制即可。
3:初始化分配的空间为零值。这一步保证了对象的实例在代码中无需赋初值即可使用。
4:为对象进行必要设置:把对象属于哪个类、元数据保存位置、哈希码、GC分代年龄等信息封装在对象头中。
5:对象初始化:执行init方法,根据程序员代码中的指令进行真正的赋值。
二:对象在内存中的存在形式
对象在内存中由三部分组成:对象头、实例数据、对齐填充。
对象头:包括两部分:
1)对象自身的运行时数据,包括:哈希码、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID等;
2)类型指针:指向对象所属类的元数据区域。
实例数据:对象真正的有效信息。
对齐填充:HotSpot虚拟机要求对象的起始地址必须是8字节的整数倍,因此对象的实例数据部分没有对齐时就需要对齐填充来补全。
三:对象的访问定位
我们通过方法中需要使用对象时,只需通过栈帧中的reference数据来访问堆中的对象内容即可。对象的访问有两种方法:句柄法、直接指针法。
句柄法:内存中划分一片区域作为句柄池,句柄池中的句柄包含了该对象到实例数据区域的指针以及到对象类型区域的指针。句柄法访问对象时,先通过reference定位到句柄池中该对象的句柄,然后由句柄中的两个指针分别访问该对象的具体实例数据和类型数据。
直接指针法:reference直接执行对象的实例数据区,而数据区中又有一个指针指向类型数据区域。
比较:句柄法比较文档,如果对象内容被移动的话,只需更改句柄池中的句柄即可,栈帧中的reference可以不改变;而直接指针法则速度更快。
四:对象已死?
判断对象是否还在内存中存活,有两种理论:
1)引用计数法:每当有一个引用执行该对象时,引用计数器+1.当计数器器的值为0时即说明对象没有被引用,已死亡。该理论的致命缺陷在于:两个对象互相引用时,彼此计数器值不为0,但又不再被访问,对象已无用却一直不会被回收。
2)可达性分析:通过一系列GCRoots对象作为起点,沿着这些节点的引用链进行检索。若一个对象没有任何引用链与GCRoots相连的话,即说明该对象不可达(不可用),可进行回收。GCRoots一般有:栈帧的引用对象、静态属性引用的对象、常量引用的对象、本地方法栈中引用的对象。
Java对象在虚拟机中的创建、内存分布、访问定位以及死亡判定的更多相关文章
- Java对象在JVM中的生命周期
当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...
- Java 对象在堆中的内存结构
翻译人员: 铁锚 翻译日期: 2013年11月8日 原文链接: What do Java objects look like in memory during run-time? 我们知道,函数每次 ...
- jvm详情——2、Java对象在jvm中的大小
Java对象的大小 基本数据的类型的大小是固定的,这里就不多说了.对于非基本类型的Java对象,其大小就值得商榷.在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任 ...
- json字符串转java对象,json中字段名称与对象属性名称不一致
json字符串转java对象,json字段名称与对象属性名称不一致可以在对象属性上添加注解@SerializedName解决
- 虚拟机中如何Linux系统如何访问PC硬盘中的文件(如何将windows下的文件夹挂载到linux虚拟机下)
这段时间决定学习嵌入式,变打算安装个Linux系统先熟悉一下Linux系统的使用,但自己电脑上安装的win7系统又不想装双系统,一是闲麻烦,二是由于对Linux系统不熟悉担心会因为自己的误操作而损坏系 ...
- JAVA虚拟机中的堆内存Heap与栈内存Stack
原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 深入Java虚拟机:JVM中的Stack和Heap 在JV ...
- java在jvm虚拟机中是如何实现多态的?
原文地址:https://blog.csdn.net/huangrunqing/article/details/51996424 众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向 ...
- 关于Java客户端连接虚拟机中的Kafka时,无法发送、接收消息的问题
kafka通过控制台模拟消息发送和消息接收正常,但是通过javaAPI操作生产者发送消息不成功 消费者接收不到数据解决方案? 1.问题排查 (1)首先通过在服务器上使用命令行来模拟生产.消费数据,发现 ...
- Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
随机推荐
- Invalid Host header 的解决方案
composer 显示:Invalid Host header的解决方案 I have tried this workaround: Edit the following line in node_m ...
- vmware桥接模式
vmware桥接模式 桥接网络是指本地物理网卡和虚拟网卡通过VMnet0虚拟交换机进行桥接,物理网卡和虚拟网卡在拓扑图上处于同等地位,那么物理网卡和虚拟网卡就相当于处于同一个网段,虚拟交换机就相当于一 ...
- Chapter 6 -- Caches
CachesExplained Explanation for how to use Guava caches. explained Updated Jun 4, 2013 by lowas...@g ...
- JEECG 命名规范
举例讲解代码规范 例如:表名 :jeecg_sys_demo 第一部分:代码文件命名规则如下: 首先:表名采用驼峰写法转换为Java代码使用单词 jeecg_sys_demo => Jeecg ...
- require.js 最佳实践【转】
https://www.cnblogs.com/digdeep/p/4607131.html require.js是一个js库,相关的基础知识,前面转载了两篇博文:Javascript模块化编程(re ...
- 如何在CentOS 7.2上创建NFS的Share,然后让Client可以访问
讲得详细清楚明白的好文. Setting Up an NFS Server and Client on CentOS 7.2 https://www.howtoforge.com/tutorial/s ...
- RxJava RxPermissions 动态权限 简介 原理 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- \r\n 如何转换成utf-8格式的,在jsp页面中正常显示换行
数据库中存的换行是\r\n,读取到UTF-8编码的JSP 页面上以后,没有换行 在jsp页面显示之前,要进行一下字符转换,将所有\r\n转换成<br>,如下: String result ...
- MYSQL数据删除数据,物理空间没释放
当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE TABLE 是指对表进行优化.如果已经删除了表的一大部分数据,或者如果已 ...
- laravel 5.5 整合 jwt 报错Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist解决
今天介绍一个在laravel5.5新版本整合jwt 执行 php artisan jwt:generate 再生成密钥时报的一个错误 Method Tymon\JWTAuth\Commands\JW ...