文档章节

深入学习java虚拟机(一)

ZHAOBEN
 ZHAOBEN
发布于 2016/04/14 21:01
字数 1926
阅读 160
收藏 5

运行时数据区域

    Java虚拟机在执行Java程序过程中把所管理的内存划分为以下几个不容的数据区域,这些区域都有各自的用途,以及创建时间和销毁时间。

    程序计数器、虚拟机栈、堆、方法区、本地方法栈


程序计数器

    背景:java 多线程是通过线程轮流切换并分配处理执行时间来实现,在任何一个时刻,一个处理器只会执行一条线程的指令。因此需要用一块内存空间记录线程的执行状态,这就是程序计数器。

    存储的内容:存放程序下一条指令的地址地方。

    目的:为了线程切换后能够恢复到正确的执行位置,每条线程都有一个独立的程序计数器。(唯一一个没有没有OutOfMemeryEror情况的区域)。“记录现场,恢复现场”


java虚拟机栈

    存放内容:局部变量表、操作数栈、动态链接、方法出口(线程私有,生命周期与线程相同。)

    虚拟机栈:是Java方法执行的内存模型。每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口。

    生命周期:每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中的的入栈到出栈过程

    局部变量表存放了编译期可知的各种基本数据类型、对象引用和returnAdderss类型

    当进入一个方法时,这个方法所需要在帧中分配多大的局部变量空间是完全确定的。方法运行期间不会改变局部变量表的大小

    Java虚拟机规范中对这个区域定义了两种异常状况:StackOverflowError(线程请求栈深度 > 虚拟机所允许的深度)。OutOfMemoryError(如果Java虚拟机动态扩展无法申请足够内存的时候)

  本地方法栈

    与虚拟机栈一致,唯一区别虚拟机栈为 java 方法服务。本地方法栈是为 native 方法服务。


    Java 堆

        目的:唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配。

            Java 堆是Java虚拟机所管理的内存中最大的一块。        

            Java堆是被所有线程共享的一块内存区域,在虚拟机启动的时候创建。

            Java 堆是垃圾回收器管理的主要区域,因此也被称为“GC堆”(垃圾堆)。

        分类:由于现在垃圾收集器基本采用分代收集算法,所以Java堆中还可以分为:新生代,老年代;再细致一点还有 Eden空间、From Survivor 空间、 To Survivor空间。

            根据Java虚拟机规范,Java堆可以处于物理上不连续的内存空间中,只要逻辑连续即可

            如果堆中没有内存完成分配实例,并且堆也无法扩展,将会抛出OutOfMemory异常

    方法区

    存储对象:它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码。方法区也被称为永久带
    与Java堆一样,是各个线程的共享的内存区域。


    深入探讨Hotspot虚拟机在Java堆中的对象分布,布局和访问的过程

    对象的创建

        虚拟机遇到 new 指令时候,首先检查指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已经被加载、解析、初始化。如果没有,那必须执行相应的类加载过程

        在类加载通过后,虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可以完全确定。

        Java 堆为对象分类内存的两种方式

        指针碰撞:假设java堆是绝对规整的,所有用过的内存放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲空间那边挪动一段与对象大小相等的距离

        空闲列表:如果Java 堆并不是规整的,已使用的内存和空闲内存相互交错,虚拟机就必须维护一个列表,记录哪些内存块是可用的。

        选择哪种方式取决于Java堆是否规整,而Java堆是否规整又取决于垃圾收集器是否带有压缩整理功能决定。

        内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值

        虚拟机对对象进行必要设置,例如找个对象是哪个类的实例,如何才能找到类的元数据信息,对象的哈希码、对象的GC分代年龄。这些信息都存放在对象的对象头中
        从虚拟机视角来看,一个新的对象已经产生,但从Java程序视角来看,对象创建才刚刚开始--<init>方法还没有执行。所有字段都还是零。执行new指令之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化。这样一个真正的对象才算完全产生。

        总结:JVM遇到new指令 —> 检查指令参数,与常量池中类符号引用匹配 & 检查类是否被加载 —> Java 堆为对象分配内存(分配内存两种方式)—> 内存空间初始化为零 & 对对象进行必要设置—> 执行init方法

    对象的内存分布

        对象在内存中存储的布局可以分为3个区域:对象头实例数据对齐填充

        对象头:包含用于存储对象自身的运行时数据类型指针

            自身运行时数据:HashCode 哈希码、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳。

            类型指针:对象指向它的类元数据的指针。如果对象是一个Java数组,那么对象头中还必须存储数组长度。

        实例数据:对象真正存储的有效信息,也是程序代码中所定义的各种类型的字段内容

        对齐填充:仅仅起占位符的作用。HotSpot VM 的自动内存管理系统的要求对象起始地址必须是8的整数倍,也就是说对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的整数倍。所以对象实例部分没有对齐时,就需要通过对齐填充来补全。

    对象的定位访问

        产生背景:Java 程序需要通过栈上的reference数据来操作堆上的具体对象。由于reference类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用该通过何种方式去定位、访问堆中的对象的具体位置。

        定位方式:句柄直接指针

            句柄:Java堆中将会划分出一块内存作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据类型数据各自的具体地址信息。




    











    

© 著作权归作者所有

ZHAOBEN
粉丝 0
博文 7
码字总数 7942
作品 0
西安
程序员
私信 提问
JVM系列开篇:为什么要学虚拟机?

跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看。所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试。但我经过了几年的学习和实战,我发现...

陈树义
2018/11/06
0
0
面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb
2018/05/12
0
0
[Java学习探讨]为什么学Java虚拟机的Java程序员更值钱?

[Java学习探讨]为什么学Java虚拟机的Java程序员更值钱? 曾经的我经常害怕处理与JVM相关的异常,对JVM的配置参数也一无所知,那时候我天真地认为,JVM的出现本身就是想让程序员屏蔽实现细节,...

原创小博客
2018/07/19
292
0
成为Java顶尖程序员 ,看这11本书就够了

“学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会。个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考、雕琢和审核的,因此从专业性的角度来说...

Java工程师-10
2017/05/23
696
3
Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
212
0

没有更多内容

加载失败,请刷新页面

加载更多

ubuntu 19.4 安装virtual

ubuntu 安装virtual 后报错 Solve “Result Code: NS_ERROR_FAILURE (0x80004005)” VirtualBox Error In Arch Linux $ sudo /sbin/vboxconfig 报错 “debconf: DbDriver ”config“: confi......

internetafei
5分钟前
1
0
思维导图技术分享

- by 文恒

程序员的自我成长
8分钟前
1
0
《将博客搬至CSDN》

将blog,也同步到CSDN中

温安适
16分钟前
2
0
watchbog再升级,企业黄金修补期不断缩小,或面临蠕虫和恶意攻击

概要 近日,阿里云安全团队发现wacthbo挖矿团伙[1]新增了CVE_2019_5475 的漏洞利用代码,并开始进行尝试性攻击。 通过对CVE_2019_5475漏洞的生命周期进行分析后发现,漏洞批量化利用的速度正...

大涛学长
19分钟前
2
0
深入理解JVM,虚拟机类加载机制

本人免费整理了Java高级资料,一共30G,需要自己领取; 传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 类加载过程概览 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的...

李红欧巴
21分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部