深入JAVA虚拟机-第二版

第一章 JAVA体系结构介绍

  • java应用程序可以使用两种类装载器,启动(bootstrap)类装载器和用户自定义装载器。
    每一个类被装载的时候,java虚拟机都监视着这个类,看它是被什么装载器装载的,当被装载的类引用了其他类的时候,
    会使用相同的类装载器去装载被引用的类。因此默认情况下只能看到被同一个类装载器装载的类,通过这种方法,java允许
    在java程序中简历多个命名空间,每一个类加载器都有自己的命名空间。
  • class 文件,运行在JVM上的二进制文件

第三章 安全(--看完再回顾本章)

  • JAVA沙箱中类装载体系结构是第一道防线
  • 防止恶意代码干涉善意代码
  • 守护被信任类库的边界
  • 将代码分类,确定该类代码可以执行些些操作
  • class 文件检测器
  • 检验字节码的的完整性
  • 类型数据语义检查
  • 字节码验证
  • 符号引用验证
  • 二进制兼容
  • JVM内置安全特性
  • 类型安全的引用转换
  • 结构化的内存访问
  • 自动垃圾收集
  • 数组边界检查
  • 空引用检查
  • 禁止对内存进行非结构化访问
  • 异常的结构化处理
  • 安全管理器和java api
  • 代码签名和认证,将一个未签名的class文件通过散列和私钥得到一个带有签名后散列的文件
  • 访问控制器

第五章 java虚拟机

  • 生命周期,main作为函数的起点,每一个程序都运行一个虚拟机实例上。java虚拟机上两种线程,一种是守护线程,另一种是非守护线程
    守护线程是由jvm自己使用的,比如垃圾回收的线程,而开始于main函数的线程是非守护线程。只要还有非守护线程在运行,虚拟机还是存活的
    ,所有非守护线程退出时,虚拟机会自动退出。

java 虚拟机的结构体系

                             -------------------
                            |   类装载器子系统    |           
                             -------------------
                                     |
    ------------------------------------------------------------------
    |    |        |         |              |                   |      |
    |  方法区      堆       java栈        PC寄存器            本地方法栈  |
    ------------------------------------------------------------------
          |                             |
       执行引擎    ————————————————>  本地方法接口

  • 一些点
  • 方法区和堆内存是由所有的线程共享的,虚拟机装载class文件时,会把类的数据放在方法区中,当程序运行时,会把根据类数据创建的对象
    放在堆内存中。
  • 当新线程被创建时,都将得到一个PC寄存器和一个JAVA栈PC寄存器总是指向下一条被执行的指令,java栈则存储方法的调用状态。(局部变量,参数返回值,运算中间值)
  • java 栈是有很多的栈帧组成,当线程调用一个方法的时候,,JVM将新的栈帧入栈,当函数返回时,栈帧被出栈。
  • 数据类型
  • 基本类型(float, double, byte, short, int, long, char, boolean, returnAddress)
    64 32 8 16 32 64 16
  • 引用类型(类,接口 ,数组)

方法区

  • 方法区的数据共享,因此是必须线程安全的。虚拟机允许程序员指定方法区的大小
  • 方法区会在内存中存储类的以下信息:
  • 类型的全限定名(包名+.+类名)

  • 此类超类的全限定名

  • 类还是接口

  • 修饰符(public ,abstruct, final)

  • 接口全限定名的有序列表

  • 类型的常量池

  • 字段信息(字段名,类型,修饰符)

  • 方法信息(方法名,类型,修饰符)

  • 一个到类ClassLoder的引用

  • 一个到Class类的引用(forName(),让用户得到已装载对象的Class实例)

  • 方法字节码

  • 操作数栈和该方法在栈帧中局部变量的大小

  • 异常表

  • 下面看一看流程

class Volcano(){
    public static void main(String args[]){
        Lava lava = new Lava();
        lava.flow();
    }
}
  • 例如我们要执行一个叫Volcano的类,当我们告诉JVMVolcano这个名字
  • JVM会找到并读入Volcano.class文件
  • 然后导入其中的二进制流,并把相应的数据存在方法区
  • 通过执行方法区中的字节码,开始执行main()方法,在执行时会一直持有指向常量池的指针
  • main方法中第一条指令是给常量池第一个类分配象的内存,于是在常量池中找到第一项,发现是对另一个类Lava的引用
  • 检查方法区,看是否被装载,发现没有被装载,于是查找Lava.class文件装载,同样把信息存储在方法区中
  • 接着指向常量池第一行的指针替换掉常量池的第一项(Lava的全限定名)-> 常量池的解析(符号引用替换成直接引用,本地指针)
  • 虚拟机准备为Lava分配内存,并用这个指针访问它的类信息,找出类信息中的需要为这个类分配多少堆内存
  • 虚拟机确定了大小,就在堆上为对象分配内存,并初始化常量值。然后把对象的引用入栈,第一条指令执行完成。
  • 接下来通过这个引用调用flow方法

两种堆设计
  • java一个虚拟实例中只有一个堆空间,所有线程共享

  • java 只有在堆中分配内存的指令,没有释放的指令,垃圾收集器会负责堆和方法区的内存回收

  • 堆和方法区一样也不是一个连续的内存区,是可扩展的

  • 堆上的对象还有一部分数据,是对象锁(互斥锁),请求可以追加,请求几次,必须释放几次,例如请求了4次,只释放了3次,那还是持有这个对象锁。

  • 堆上对象还有一部分数据与垃圾收集器有关,垃圾回收器必须跟踪每个对象。

  • 数组是一个对象,总是存储在堆中

  • PC(程序计数器)寄存器,在每个线程中有一个,它有一个字的大小,存储一个本地指针,总是指向下一条将要执行的指令。

java 栈

过程
  • 每当启用一个线程,JVM会为它分配一个java 栈。
  • 栈帧的组成
  • 局部变量区 -> 一个数组,以字(32bit)为单位,类型int,float,returnAddress的值再数组中占一项,byte,short,char会被转化成int,也占一项,double,long占2项。任何一个实例方法(非static),的数组第一项都是对象本身的reference.
  • 操作数栈 -> byte,short,char会被转化成int,和上面一样,只有在存回堆中是会被转化为原来类型。他也是一个数组,但是按照栈操作来访问。由于java虚拟机没有寄存器,java的指令是通过操作数栈中取得操作数的。
  • 栈帧数据,支持常量池的解析正常方法返回和异常派发机制的数据。
    为了处理执行期的异常退出情况,帧数据区保存一个对此方法的异常表的引用。当方法抛出异常,会在异常表中查找对应的异常,如果找到了匹配的catch语句,就会交给ccatch中的代码处理,如果没有则异常中止。
  • 两站不同的虚拟机实现的帧分配


  • 本地方法栈,取决于设计者的实现

执行引擎(没看太明白)

  • 运行中java程序的每一个线程都是一个独立的虚拟机执行引擎的实例。
  • 从线程的生命周期开始,它要么在执行字节码,要么在执行native方法。
  • 指令集,指令集关注的中心是操作数栈。操作数栈中的数值必须按照适合他们类型的方式使用。比如压入栈4个int,却把他们当做两个long来做操作,是非法的 。

第六章 JAVA class文件 (粗略看)

  • java class文件是对java程序二进制文件的精确定义。一个class文件中指包括一个class 或者interface.

  • class文件不一定与java语言有关,别的语言也可以编译成class文件在虚拟机上运行。

  • class 文件组成
  • magic ,每个class文件的前四个字节 0xCAFEBABE,用来分辨是否是class文件。
  • minor_version major_version b版本号。
  • constant_pool_count 常量池的数量,constant_pool 常量池
  • access_flags 类的修饰信息,public ,private ,static 等
  • this_class 指向常量池的索引
  • super_class 超类常量池索引

第七章 类型的生命周期

  • 类主动装载的时机
  • 创建实例时(new, 反射,克隆,反序列化)
  • 调用类中的静态方法
  • 使用类或接口的静态字段或者对字段赋值(final 修饰的静态变量除外,它被初始化为一个编译时的常量表达式)
  • 调用api反射方法
  • 初始化子类
  • 含有main函数的类
  • 所有类的初始化都要求它的超类在此之前初始化了。(接口不是)
  • 装载
  • 通过完全限定名产生一个二进制流
  • 解析二进制文件
  • 创建一个该类型Class实例
  • 初始化
  • 所有类变量初始化语句和类型的静态初始化器都被java编译器收集到一起放在一个特殊的方法<clinit>中,并非所有的类都有这个方法。
  • 如果多个线程需要初始化一个类,仅仅允许一个线程来执行初始化,其他线程需要等待。完成后需要通知其他等待线程。
对象生命周期
  • 实例化
  • new

  • reflect.newInstance()

  • clone()

  • ObjectInputStream.getObject

  • 堆中分配内存,然后赋予实例变量初始值

  • 类型当没有引用的时候会被卸载,同样通过垃圾回收器。

第八章 链接模型

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

推荐阅读更多精彩内容

  • JAVA虚拟机的生命周期 一个运行时的Java虚拟机实例的天职是:负责运行一个java程序。当启动一个Java程序...
    Solang阅读 1,169评论 0 19
  • 《深入理解Java虚拟机》笔记_第一遍 先取看完这本书(JVM)后必须掌握的部分。 第一部分 走近 Java 从传...
    xiaogmail阅读 5,070评论 1 34
  • 生活在节奏快的21世纪,我们不敢懈怠生活。因为只要我们稍微懒惰了一下,就会落后别人一大截。所以我们只能不断的让自己...
    苏黎来世阅读 143评论 0 0
  • 常想起那丛花 那丛长在山脚岩石堆里的草花 少有经过的路人 不知是否有注意到它 停下脚步欣赏它的美丽 它美的独特 美...
    且惜且爱阅读 341评论 3 6
  • 《小王子》算是很小的时候就看过的书了,随着年龄增长,每一次看都有不一样的感觉,但每一次看都有同样的感觉,这真的是一...
    惊蛰小喵阅读 488评论 0 0