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

JDK技术组成.png

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

传统意义上,Java包括了:

  • Java程序设计语言
  • 各种平台上的Java虚拟机(JVM)
  • class文件格式
  • Java API
  • 第三方Java库

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

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

内存管理

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

Java虚拟机运行时数据区
  • 程序计数器
    标记当前线程程序执行到的位置,这样可以方便线程切换时恢复到正确的执行位置。所以计数器是线程私有数据。
  • 虚拟机栈
    初学Java的时候,老师喜欢把Java内存模型分为堆内存和栈内存,栈内存就是这玩意儿,是Java方法执行的内存模型,每个方法执行的时候都会创建一个栈帧(Stack Frame) 存储局部变量,操作数栈,动态链接,方法出口等。
    所以堆内存和栈内存的分类是比较粗糙的,实际上要复杂的多。
    在虚拟机中,如果线程请求的深度大于栈的深度就会出现StackOverflowError错误,如果是动态扩展的栈,当扩展无法获得足够的内存会抛出OutOfMemoryError错误
  • 本地方法栈
    执行Native方法的服务,具体看JVM的实现,方便程序调用本地的方法与服务。
  • Java堆
    Java堆是被一群线程共享是一块内存,应该是最大的一块存储空间了。在虚拟机启动时创建,GC管理的最大的一块地方。这里可以划分出多个线程私有的缓冲区,但是这些划分与存放内容无关,这里主要存的,是对象。当然,这里是可拓展的。
  • 方法区
    存放虚拟机加载的类信息,常量,静态变量,即时编译的代码数据。
  • 运行时常量池
    是方法区的一部分,Class文件除了类版本,字段,方法,接口等描述信息外,还有一项是常量池,存放编译时,生成的各种字面量,符号引用,这部分内容将在类加载后进入方法区的运行时常量池内

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

对象的创建

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

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

对象的访问定位

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

句柄访问简单示意图

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


指针访问简单示意图

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容

  • JVM内存模型Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: ...
    光剑书架上的书阅读 2,497评论 2 26
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,222评论 11 349
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,575评论 3 83
  • 在用户根目录下创建文件名为 .vimrc 的系统文件添加内容 set tabstop=4 set shiftwid...
    风亡小窝阅读 324评论 0 0
  • 茅草屋内,他突然吹灭了眼前的烛光。房门推开,一道剑光闪过,一把长剑架在了来客的脖子上。 但来人似乎早已预料到了这种...
    斟茶公子阅读 436评论 0 4