程序猿首页投稿(暂停使用,暂停投稿)程序员

简单说说jvm的对象存储与访问

2016-05-10  本文已影响368人  MaxZing
JDK技术组成.png

图上所涉及的是Java的技术组成,确实,没有必要全部深入了解。但是大致的框架是有必要明确的。业务层的程序员可能并不了解这些,所以我还是弄一篇笔记用来学习和分享

传统意义上,Java包括了:

jvm是Java最小运行环境,JDK是Java最小开发环境

想知道对象怎么创建的,就要先知道,JVM的内存管理,先介绍一下

内存管理

Java比C++多了一个内存管理,减少了程序员对内存回收的操作,方便的同时也带来了新的麻烦,所以我们需要了解Java的内存管理技术,避免过于浪费性能。

Java虚拟机运行时数据区

上面说了这么多,那Java是怎么创建对象的呢?

对象的创建

当虚拟机获得new指令的时候,首先会在常量池中找到类符号引用,检查符号是否被加载、解析、初始化过,检查通过以后执行未执行的操作,然后虚拟机会为新对象分配内存(把一块确定大小的内存从堆中分出来)。
在规整的Java堆内存中(用过的内存放在一边,没用过的内存放在另一边,中间靠一个指针来分开),分配的内存就是将指针移动一下,让出对象对应大小的位置。而在非规整的堆内存中,空闲与非空闲的相互交错,这时候,Java会维护一个列表,记录内存可用的区块,分内存给对象的时候,就是找到一块足够大的地方,存下这个对象,并更新记录表。不同的JVM有不同的记录方式。

这样分配如何保证线程安全呢,即使在仅仅改变内存指针的行为,在并发情况下,也不是安全的,可能线程A正在给对象分配内存,还没来得及修改,而线程B却使用了老的指针地址。这样,要么对修改指针做同步处理,要么把内存分配动作按线程划分在不通空间(本地线程分配缓冲)。分配完,对内存进行清零,让后对对象进行初始化。将对象的哈希码,GC分代年龄存放在对象头中。

对象的访问定位

访问对象要靠栈上的reference数据寻址。Java没有定义这个引用如何定位,所以有两种方式访问。(句柄访问,指针访问)
句柄访问:栈reference中存储的是句柄的地址,对应的堆的句柄池内的数据。如图:

句柄访问简单示意图

指针访问:指针直接访问对象


指针访问简单示意图

句柄访问存储比较稳定,对象移动的时候只需要改变指针内的地址,reference内的数据不用改变,指针直接访问速度更快,节省开销。

虽然Java有GC,但是GC不是万能的,内存溢出还是会存在。所以应该说了解JVM,应该也是是Java程序员的必修课之一吧。

上一篇 下一篇

猜你喜欢

热点阅读