JVM总结(2)java内存区域、字节码执行引擎

1、内存区域

程序计数器:知道线程执行位置,保证线程切换后能恢复到正确的执行位置。

虚拟机栈:存栈帧。栈帧里存局部变量表、操作栈、动态连接、方法返回地址。局部变量表又存了各种基本数据类型和对象引用(句柄)。

本地方法栈:为Native方法服务

堆:存放对象实例和数组,可以处于物理上不连续的内存空间

方法区:存类信息、常量、静态变量。有运行时常量池,存放类的符号引用

堆主要用来存放对象,栈主要用来执行程序。

2、对象的创建

虚拟机遇到一条new指令时,会先去常量池检测能否找到new对应的类的符号引用,并检测这个类是否加载、初始化。

如果加载检查通过,则分配内存。分配内存有两种方式:⑴指针碰撞,针对连续内存区域;⑵空闲列表,针对不连续内存区域。

内存分配完之后,会对内存初始化零值,保证实例字段能在java代码不赋初值也能使用。

接下来对对象信息进行设置,把类的元数据信息、对象的哈希码、对象的GC分代年龄等信息存放在对象头之中。

最后执行用户的Init方法

3、对象的内存布局

分为三部分,对象头、实例数据、对齐填充

对象头:⑴对象自身运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁等。⑵类型指针,虚拟机通过这个来确定这个对象是哪个类的实例。⑶如果对象是一个Java数组,那么对象头中还必须有一块用于记录数组长度的数据。

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

对齐填充:JVM要求对象的起始地址必须是8字节的整数倍,因此当对象实例数据没有对齐时,这部分来补全。

对象的访问定位

取决于虚拟机的实现而定,有“句柄”和“直接指针”两种方式

“句柄”的好处是,在对象被移动(垃圾回收时很普遍),只用修改句柄中的实例数据指针,而reference本身不用修改。

“直接指针”的好处是,速度更快,毕竟节省了一次指针定位的时间开销。由于对象的访问在Java中非常频繁,因此这部分开销节省下来也很可观。

JVM字节码执行引擎

字节码文件即类文件被加载后,就能送入执行引擎了:

输入:字节码文件

处理:字节码解析

输出:执行结果。

物理机的执行引擎是由硬件实现的,虚拟机的执行引擎由于自己实现的。

• 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。

• 每个栈帧都包括了一下几部分:局部变量表、操作数栈、动态连接、方法的返回地址 和一些额外的附加信息。

• 每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。

• 一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法,执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。

局部变量表:

一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。以变量槽slot为单位,一个slot可以放32位数据类型,对于long\double占用2个slot。

 

操作数栈:

即用来存放操作数的栈结构,当一个方法刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令向操作数栈中写入和提取内容,也就是入栈和出栈的操作。

java虚拟机的解释执行引擎称为基于栈的执行引擎,其中所指的栈就是操作数栈。

动态连接:

运行期将相关的符号引用转换为直接引用

方法返回地址:

方法执行完成的结果值

方法调用:

解析方法的符号引用和确定方法的版本

方法的执行:

解释执行(通过解释器执行)

编译执行(通过JIT编译器产生本地代码执行)

基于栈的代码执行示例

下面我们用简单的案例来解释一下JVM代码执行的过程,代码实例如下:

使用javap指令查看字节码:

 
 

JVM总结(二)的更多相关文章

  1. JVM(二)Java虚拟机组成详解

    导读:详细而深入的总结,是对知识"豁然开朗"之后的"刻骨铭心",想忘记都难. Java虚拟机(Java Virtual Machine)下文简称jvm,上一篇我 ...

  2. JVM总括二-垃圾回收:GC Roots、回收算法、回收器

    JVM总括二-垃圾回收:GC Roots.回收算法.回收器 目录:JVM总括:目录 一.判断对象是否存活 为了判断对象是否存活引入GC Roots,如果一个对象与GC Roots没有直接或间接的引用关 ...

  3. JVM(十二):方法调用

    JVM(十二):方法调用 在 JVM(七):JVM内存结构 中,我们说到了方法执行在何种内存结构上执行:Java 方法活动在虚拟机栈中的栈帧上,栈帧的具体结构在内存结构中已经详细讲解过了,下面就让我们 ...

  4. 深入JVM(二)JVM概述

    深入JVM(一)JVM指令手册 深入JVM(二)JVM概述 一.JVM的原理 Java虚拟机是Java平台的基石,解决了硬件和操作系统的相互独立性.不同平台(Windows,Linux和MacOS)的 ...

  5. JVM系列二:GC策略&内存申请、对象衰老

    JVM里的GC(Garbage Collection)的算法有很多种,如标记清除收集器,压缩收集器,分代收集器等等,详见HotSpot VM GC 的种类 现在比较常用的是分代收集(generatio ...

  6. JVM的生命周期——JVM之二

    一.首先分析两个概念 JVM实例和JVM执行引擎实例 (1)JVM实例对应了一个独立运行的java程序——进程级别 一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程 ...

  7. jvm系列 (二) ---垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...

  8. JVM(二)JVM内存布局

    这几天我再次阅读了<深入理解Java虚拟机>之第二章"Java内存区域与内存溢出异常",同时也参考了一些网上的资料,现在把自己的一些认识和体会记录一下.  (本文为博主 ...

  9. JVM学习二:垃圾收集(Garbage Collection,GC)机制

    JVM的GC分为两个主要部分,第一部分是判断对象是否已死(堆内存的垃圾回收占主要部分,方法区(metaspace)的内存回收在最新的官方文档中未给出详细解释,暂时不做讨论范围),第二部分是对内存区进行 ...

  10. JVM(二)—— 垃圾回收

    垃圾回收 垃圾回收主要解决三个问题(回收哪些Which,什么时候回收WHEN,如何回收HOW) 一.回收哪些 这三个问题,最主要的还是第一个,Which回收哪些,评断回收还是不回收的标准是看对象是否被 ...

随机推荐

  1. 跟我学SpringCloud | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪

    SpringCloud系列教程 | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪 Springboot: 2.1.6.RELEASE SpringCloud: ...

  2. 用链表和数组实现HASH表,几种碰撞冲突解决方法

    Hash算法中要解决一个碰撞冲突的办法,后文中描述了几种解决方法.下面代码中用的是链式地址法,就是用链表和数组实现HASH表. he/*hash table max size*/ #define HA ...

  3. C++11/14笔记

    目录 语言层面 模板表达式中的空格 nullptr和std::nullptr_t 自动推导类型----auto 一致性初始化----Uniform Initialization 初始化列表(initi ...

  4. 哈工大计算机网络Week2-网络应用数据交换

    目录 网络应用数据交换 P2P应用:原理与文件分发 纯P2P架构 文件分发:客户机/服务器 vs. P2P CS 为什么是这样的?不应该传送和发出难道是并行的??? P2P P2P文件分发典型例子:B ...

  5. jekyll搭建个人博客2

    目录 个性化 jekyll目录结构 修改个人信息 修改头像 修改背景颜色 关于头像的效果 图片问题 域名 个性化 jekyll目录结构 个性化就是要对文件内容作出修改,使得博客外观发生变化,在修改文件 ...

  6. Zeppelin0.5.6使用spark解释器

    Zeppelin为0.5.6 Zeppelin默认自带本地spark,可以不依赖任何集群,下载bin包,解压安装就可以使用. 使用其他的spark集群在yarn模式下. 配置: vi zeppelin ...

  7. JVM(九):垃圾回收算法

    JVM(九):垃圾回收算法 在本文中,我们将从概念模型的角度探讨 JVM 是如何回收对象,包括 JVM 是如何判断一个对象已经死亡,什么时候在哪里进行了垃圾回收,垃圾回收有几种核心算法,每个算法优劣是 ...

  8. Linux mysql开启远程访问

    默认情况下远程访问会出现 Can't connect to MySQL server on '192.168.10.18′ (10061) 错误是因为,mysql的默认配置为了增强安全性,禁止了非本机 ...

  9. Java程序员注意——审查Java代码的六种常见错误

    代码审查是消灭Bug最重要的方法之一,这些审查在大多数时候都特别奏效.由于代码审查本身所针对的对象,就是俯瞰整个代码在测试过程中的问题和Bug.并且,代码审查对消除一些特别细节的错误大有裨益,尤其是那 ...

  10. python课堂整理2

    一.字节和编码 1个字节是8位二进制 utf-8 表示一个中文要用3个字节 gbk 为中国汉字发明,2个字节可表示汉字 所以 utf-8 可以读gbk编码,而gbk去读utf-8 的内容会乱码 uni ...