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(); ...
随机推荐
- 通过xml文件来设置动画
@android:anim/accelerate_interpolator: 越来越快 @android:anim/decelerate_interpolator:越来越慢 @android:anim ...
- JAVAWEB开发之HttpServletResponse和HttpServletRequest详解(上)(各种乱码、验证码、重定向和转发)
HttpServletResponse简介 Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象 request和re ...
- 使用 Golang 编写链代码 (v0.6 )
https://www.ibm.com/developerworks/cn/cloud/library/cl-ibm-blockchain-chaincode-testing-using-golang ...
- 通过pycharm使用git
前言 使用git+pycharm有一段时间了,算是稍有点心得,这边整理一下,可能有的方法不是最优,欢迎交流,可能还是习惯敲命令去使用git,不过其实pycharm已经帮忙做了很多了,我们可以不用记住那 ...
- 用Eclipse开发Androd应用程序时,自带虚机模拟器太慢了,怎么办
问:用Eclipse开发Androd应用程序时,系统自带模拟器太慢了,怎么办? 答:用Genymotin
- google chrome 删除重复的书签 about sync
之前 由于 谷歌 同步的不智能,且不询问用户同步方法和细节,导致我的书签包括了大量重复的书签,想去除重复的书签. 由于谷歌书签文件 存储在:C:\Documents and Settings\Admi ...
- 解决MTP device安装失败,手机无法被读取
操作步骤: 1. 我的电脑—>管理—>设备管理器—>便携设备(MTP)-->右击-更新驱动 2. 选择浏览计算机以查找驱动程序软件—>从计算机列表选择—>MTP ...
- android 很多应用中用到的 listView + viewPager
比如网易啊啥的, 有些界面的 listview 第一行是可以 左右滑动的 viewpager,当滑动下面listView的时候 会一起滑动上去 工程目录: 效果图: ...
- AltiumDesigner PCB布局布线过程与技巧
首先是原理图设计. 原理图设计是前期准备工作,对简单的板子,如果熟练流程,不妨可以跳过.但是对于初学者一定要按流程来,这样一方面可以养成良好的习惯,另一方面对复杂的电路也只有这样才能避免出错.在画原理 ...
- OpenCV学习记录之摄像头调用
关于opencv调用摄像头的问题主要是因为摄像头的打开有延时.在显示图像前,要用if语句判断图像是否存在.(否则会报错) 具体的:教程里的源程序,将if条件句里,break去掉,并增加else语句. ...