澳门新葡萄京娱乐场 2

澳门新葡萄京娱乐场《深入理解Java虚拟机(第2版)》

在利用中,我们反复必要一个常量文件,用于存款和储蓄被多个地点援用的共享常量。在规划使用时,小编也碰着了就像是的景况,相当多地点都急需有滋有味的常量。

类加载的空子

类从被加载到虚构机内部存款和储蓄器早先,到卸载出内存开端,生命周期包蕴八个等级

澳门新葡萄京娱乐场 1

类加载工程

当中”验证“,”绸缪“,”解析“八个部分统称为三番五次(LinkingState of Qatar

对此开首化,设想机是严酷规定了有且唯有各样情况必得立即对类举办”初阶化“

  • 1.会面 new, getstatic, putstatic, 或invokestatic
    那4条字节码指令,若无开头化则先带头化。那4条指令对应的java代码场景是:

    • 利用 new 关键字实例化对象的时候
    • 读取或设置八个类的静态字段(被final修饰,已在编写翻译期把结果归入常量池的静态字段除此之外卡塔尔
    • 调用叁个类的静态方法的时候
  • 2.选择java.long.reflect包的不二等秘书诀对类实行反射调用,即使类未有最初化则先带头化

  • 3.当开首化类时,如察觉父类未有早先化,则先初阶化父类

  • 4.当虚构机运转,客户要求钦赐贰个实践的主类(满含main(State of Qatar方法的极度类State of Qatar,设想机遇先开首化这几个主类。

那八种情景称为对二个类举行主动援引。除外全体援引称为被动引用,都不会触发初阶化。
下边包车型地铁代码是被动引用的例子

package org.fenixsoft.classloading;

/**
* 被动使用类字段演示一:
* 通过子类引用父类的静态字段,不会导致子类初始化
**/
public class SuperClass {

    static {
        System.out.println("SuperClass init!");//会输出
    }

    public static int value = 123;
}

public class SubClass extends SuperClass {

    static {
        System.out.println("SubClass init!");//不会输出
    }
}

/**
* 非主动使用类字段演示
**/
public class NotInitialization {

    public static void main(String[] args) {
        System.out.println(SubClass.value);
    }

}

上边代码只触发父类伊始化,子类不会开始化。对于静态字段,唯有一贯定义那些字段的类才会被开端化。

package org.fenixsoft.classloading;

/**
* 被动使用类字段演示二:
* 通过数组定义来引用类,不会触发此类的初始化
**/
public class NotInitialization {

    public static void main(String[] args) {
        SuperClass[] sca = new SuperClass[10];
    }

}

上述代码未有出口”SuperClass
init!”.这段代码触发了名叫”[Lorg.fenixsoft.classloading.SuperClass“的类的起先化,那不是合法的类名称,是由java虚构机自动生成的,直接接轨与Object的子类,创设动作由字节码指令newarray触发。

以此类代表了四个因素类型为”org.fenixsoft.classloading.SuperClass”的一维数组。

package org.fenixsoft.classloading;

/**
* 被动使用类字段演示三:
* 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定   义常量的类的初始化。
**/
public class ConstClass {

    static {
        System.out.println("ConstClass init!");//不会输出
    }

    public static final String HELLOWORLD = "hello world";
}

/**
* 非主动使用类字段演示
**/
public class NotInitialization {

    public static void main(String[] args) {
        System.out.println(ConstClass.HELLOWORLD);
    }
}

上述代码未有出口”ConstClass init!“因为在编写翻译阶段将此常量的值”hello
world”存款和储蓄到NotInitialization类的常量池中了。对常量ConstClass.HELLOWOPRADOLD的引用转形成NotInitialization类对自己常量池的引用了。也正是说NotInitialization的class文件之中未有ConstClass类的号子援引入口,这多个类在编写翻译成class之后就不设有任何交流了。

前言

自己明确需求八个独门的文书来积累那个静态公共常量。不过自个儿不是特意规定是应该用接口还是类(枚举不知足自己的急需)。小编有三种采用:

接口与类加载的进度有两样,重要分裂在于:

  • 当多少个类在初步化时,要求其父类举办开端化。但是当一个接口在早先化时,并不要求其父接口全体都产生开首化,唯有在真的使用到父接口的时候(如引用接口中定义的常量卡塔尔才会开首化。

先是有的 走近Java

应用接口,如:

类加载器

第1章 走近Java

package one;
public interface Constants {
String NAME="name1";
int MAX_VAL=25;
}

类与类加载器

比较八个类是还是不是”相等”,只有在此四个类是由同贰个类加载器加载的前提下才有意义。不然固然多少个类是发源同二个class文件,只要加载它们的类加载器分歧,那七个类就必定将不对等。

这里的”相等“满含代表类的class对象的equals(State of Qatar方法,isAssignableFrom(卡塔尔,
isInstance(State of Qatar方法的回到结果,也席卷了应用instanceof关键字做靶子所属关系判别等状态。

/**
* 类加载器与instanceof关键字演示
* 
* @author zzm
*/
public class ClassLoaderTest {

    public static void main(String[] args) throws Exception {

        ClassLoader myLoader = new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws   ClassNotFoundException {
            try {
                String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                InputStream is = getClass().getResourceAsStream(fileName);
                if (is == null) {
                    return super.loadClass(name);
                }
                byte[] b = new byte[is.available()];
                is.read(b);
                return defineClass(name, b, 0, b.length);
            } catch (IOException e) {
                throw new ClassNotFoundException(name);
            }
        }
    };

    Object obj = myLoader.loadClass("org.fenixsoft.classloading.ClassLoaderTest").newInstance();

    System.out.println(obj.getClass());
    System.out.println(obj instanceof org.fenixsoft.classloading.ClassLoaderTest);
}
}

运营结果:
class org.fenixsoft.classloading.ClassLoaderTest
false

虚构机中设有八个ClassLoaderTest类,类加载器不相同。

1.1 概述

老人委派模型

  • 运转类加载器(Bootstrap ClassLoader卡塔尔(قطر‎:
    C++语言达成,是虚构机本身的一片段。肩负将存放在<JAVA_HOME>lib目录中的类库加载到虚构机内部存款和储蓄器中。运维器类加载器不能被java程序间接援用。

  • 闻一知十类加载器(Extension ClassLoaderState of Qatar:
    负担加载<JAVA_HOME>libext目录中的,大概被java.ext.dirs系统变量所钦命的门路中的全数类库,开荒者可平素动用扩大类加载器。

  • 应用程序类加载器(Application
    ClassLoader卡塔尔国:由于那个类加载器是ClassLoader中的getSystemClassLoader(State of Qatar方法的重临值,所以日常也称之为系统类加载器。它担当加载客商类路线(ClassPath卡塔尔(قطر‎上所钦定的类库,开辟者可直接运用那个类加载器。如若应用程序中从不自定义过本人的类加载器,平时景观下那一个正是前后相继中默许的类加载器。

  • 自定义类加载器

澳门新葡萄京娱乐场 2

模型

  • 流程是当一个classlaoder尝试加载一个类时,它会先抛给父加载器,一偶发的往上抛,抛到最上层运转类加载器。纵然开发银行类加载器无法加载,这时候会自上而下的抛给此外类加载器,直到能够加载甘休

父老母委派模型的落实

protected synchronized Class<?> loadClass(String name, boolean resolve)     throws ClassNotFoundException {
    //首先,检查请求的类是否已经被加载过了
    Class c = findLoadedClass(name);
    if (c == null){
        try{
            if (parent != null){
                c = parent.loadClass(name,false);
            }else {
                c = findBootstrapClassOrNull(name);
            }
        }catch(ClassNotFoundException e){
            //如果父类加载器抛出异常
            //说明父类加载器无法完成加载请求
        }
        if(c == null){
            //在父类加载器无法加载的时候
            //再调用本身的findClass方法来进行类加载
            c = findClass(name);
        }
    }
    if (resolve){
        resolveClass(c);
    }
    return c ; 
}

参考:

《浓重领会java设想机》周志明 著

1.2 Java技巧系统

package two;
public class Constants {
public static final String NAME="name1";
public static final int MAX_VAL=25;
}

1.3 Java发展史

自己的意见是行使接口。因为接口会自行将成员变量设置为静态的(static)、不可变的(final),那或多或少得以免备有个别景况下错误地增加新的常量。那也使得代码看起来更简便和明显。

1.4 Java虚构机发展史

而且,三个的轻松测验突显,相通的接口(字节码文件)占用的空间是209个字节(ubuntu
14.04机器上),而类(字节码文件)占用的长空是3陆20个字节(同样的操作系统)。越来越少的字节码文件表示加载和保证的本钱更低。此外,JVM
加载接口的时候,无需担忧类提供的额外特征(如重载、方法的动态绑定等),由此加载更加快。

1.4.1 Sun Classic Exact VM

那看起来特别好,但是那是八个超人反情势的例证。尽管接受接口来保存常量看起很有扶植,然而那给采取早先时期的恢宏留下二个漏洞。

1.4.2 Sun HotSpot VM

一经存在在叁个类,紧凑】注重于这个常量。开采者在那类中写满了经过接口对常量的引用。如:

1.4.3 Sun Mobile-Embedded VM Meta-Circular VM

packagename.Constant.CONSTANT_NAME

1.4.4 BEA JRockit IBM J9 VM

进而,为了“清理”这段代码,他恐怕想完结该接口,那样她就无需外省写“packagename.Constants”,全部的常量能够一贯访谈。

1.4.5 Azul VM BEA Liquid VM

不过,一旦他促成了该接口,全部的常量就都成为“合同”(因为具有的常量都是集体的、静态的)的一有的。那造成为这些类扩充了没有须要的常量。那会动摇整个底工,并引起混乱。Java
中从未一种方法得以阻碍类完毕接口。

1.4.6 Apache Harmony Google Android Dalvik VM

而另一种方法,大家能够将类设置为final,那样就不能够扩充。以致,大家得以将布局器设置为私有的,以免守对那个类实例化,那样就永世不会损坏约定。此外,假使二个奇特的常量在同二个类中被一再用到,则开荒者能够应用静态引进。

1.4.7 Microsoft JVM及其他

有着对于常量类,相比好的安顿性应该是:

1.5 远望Java本领的前程

package three;
//make the class non-extendable by adding final 增加final关键字来避免继承
public final class Constants {
//Hide the constructor 隐藏构造器
private Constants(){}
public static String NAME="name";
}

1.5.1 模块化

静态引进的例证:

1.5.2 混合语言

import static three.Constants.NAME;
public class UseConstants {
  public static void main(String[] args) {
      System.out.println("the value of constants is"+NAME);
  }
}

1.5.3 多核并行

其一规划难点也称为接口常量反方式(Constant Interface Anti-pattern)。

1.5.4 进一层拉长语法

1.5.5 陆十一人设想机

1.6 实战:本身编译JDK

1.6.1 获取JDK源码

澳门新葡萄京娱乐场,1.6.2 系统须求

1.6.3 营造编写翻译景况

1.6.4 进行编写翻译

1.6.5 在IDE工具中进行源码调节和测验

1.7 本章小结

第3盘部 自动内部存款和储蓄器处理机制

第2章 Java内部存款和储蓄器区域与内部存款和储蓄器溢出拾贰分

2.1 概述

2.2 运营时数据区域

  • 线程分享:
    • 堆(Heap):OutOfMemoryError
    • 方法区(Method Area):OutOfMemoryError
  • 线程私有:
    • 次第流速計(Program Counter
      Register):独一未有明确OutOfMemoryError的区域
    • 编造机栈(VM Stack,java方法): OutOfMemoryError,
      StackOverflowError
    • 本地点法栈(Native Method
      Stack,本地点法):OutOfMemoryError,StackOverflowError

OutOfMemoryError(内部存储器泄漏):设想机能够动态扩大,假诺扩充是无法申请到丰富的内部存款和储蓄器时;
StackOverflowError(栈溢出):线程央浼的栈深度当先设想机所允许的纵深时;

2.2.1 程序流速計

前后相继计数器(Program Counter
Register):是一块十分小的内部存款和储蓄器空间,能够看作是脚下线程狠抓施的字节码行号提醒器
字节码提醒器干活时便是因此转移那些计数器的值来筛选下一条须求施行的字节码指令(分支、循环、跳转、万分处理、线程苏醒等底子作用皆以重视于这一个计数器来达成的。)。
Java虚构机的八线程是经过线程轮换切换并分配微处理器施行时间的点子来兑现的,在规定的时刻,一个Computer都只会管理的三个线程中的指令。
所以,为了线程切换后能够还原到正确的实行职位,每条线程都急需有二个独自的主次流量计,互不影响,独立存款和储蓄,那类的内部存款和储蓄器区域称为“线程私有”的内部存款和储蓄器。

2.2.2 Java设想机栈

Java设想机栈也是线程私有的,生命周期与线程相像。
汇报的是Java方法实践的内部存款和储蓄器模型

  • 每种方法在试行时都会成立叁个栈帧(Stack
    Frame)用于存款和储蓄某些变量表操作数栈动态链接主意说话
    等信息。
  • 每多个艺术从调用直至实现的经过,就相应四个栈帧在假造机栈中的入栈到出栈的进程。

2.2.3 当地点法栈

与Java虚构机栈所发挥的效应是分外相同的,差别在于:

设想机栈为虚构机实行Java方法(也便是字节码)服务,
而,当地点法栈则为:虚构机所用到的Native方法服务。

2.2.4 Java堆

装有线程分享的一块内部存款和储蓄器区域。独一目的就是:寄放对象实例
Java堆是垃圾堆回笼器拘系的首要区域,又称“GC堆”:(Garbage Collected
Heap);

  • 内部存储器回笼角度:
    • 分代回收算法
    • 粗分:新生代、老年代
    • 分开:Eden空间、From Sur华为r空间、To SuriPhoner空间等您。
  • 内部存款和储蓄器分配角度:线程分享的Java堆或然划分出两个线程私有的分配缓冲区(Thread
    Local Allocation Buffer,TLAB)

2.2.5 方法区

字节码中方法表;
方法区是线程共享的,用于存款和储蓄已被设想机加载的类信息常量静态变量即时编写翻译器编写翻译后的代码的数据。
HotSpot虚构机的GC分代收罗器增添至当方法区,使用恒久代来兑现方法区——所以又叫做“长久代”(Premanent
Generation)。那个区域的内部存款和储蓄器回笼目的根本是:针对常量池的回笼和对项目标卸载。

方法区就算称之为 非堆 ,但其实在内部存款和储蓄器之中,也是一种非凡的

堆是极其用来寄存对象的,而方法区(一种特殊的堆)是用来
留存描述方法新闻对象

方法区寄放着类的运行时数据:

  1. 静态变量(静态域)
  2. 静态方法
  3. 常量池
  4. 类的代码

<-
寄存着对象:

  • java.lang.class:代表着方法区的类(java中万物皆对象:Class也是目的。)

<-
main方法的栈帧:

2.2.6 运转时常量池

运营时常量池(Runtime Constant
Pool)是方法区的一有个别。Class文件中除了有类的版本、字段、方法、接口等描述音信外,还应该有一项新闻正是常量池(Constant
Pool
Table),用于存放编写翻译期生成的各类字面量和符号援引,那有的内容就要类加载后步向方法区的周转时常量池中寄存。

2.2.7 直接内部存储器

直接内部存款和储蓄器(Direct
Memory)并不是虚构机运行时数据区的一片段,亦不是Java设想机标准中定义的内部存款和储蓄器区域。

NIO类,引进了一种基于通道(Channel)与缓冲区(Buffer)的I/O情势,能够接收Native函数库来向来分配堆外内部存款和储蓄器,然后经过三个囤积在Java堆中的DirectByteBuffer对象作为那块内存的引用举办操作。显著拉长品质,因为制止了Java堆和Native堆中来回复制数据。

2.3 HotSpot虚构机对象探秘

2.3.1 对象的创设

2.3.2 对象的内部存储器布局

2.3.3 对象的走访定位

2.4 实战:OutOfMemoryError异常

2.4.1 Java堆溢出

2.4.2 设想机栈和本地方法栈溢出

2.4.3 方法区和平运动作时常量池溢出

2.4.4 本机直接内部存款和储蓄器溢出

2.5 本章小结

第3章 垃圾搜集器与内部存款和储蓄器分配政策

3.1 概述

3.2 对象已死吧

3.2.1 援用计数算法

3.2.2 可达性解析算法

3.2.3 再谈引用

3.2.4 生存照旧一命归西

3.2.5 回笼方法区

3.3 垃圾收罗算法

3.3.1 标识-解除算法

3.3.2 复制算法

3.3.3 标识-收拾算法

3.3.4 分代收罗算法

3.4 HotSpot的算法落成

3.4.1 枚举根节点

3.4.2 安全点

3.4.3 安全区域

3.5 垃圾搜聚器

3.5.1 Serial收集器

3.5.2 ParNew收集器

3.5.3 Parallel Scavenge收集器

3.5.4 Serial Old收集器

3.5.5 Parallel Old收集器

3.5.6 CMS收集器

3.5.7 G1收集器

3.5.8 理解GC日志

3.5.9 垃圾搜罗器参数总括

3.6 内部存款和储蓄器分配与回收战术

3.6.1 对象优先在艾登分配

3.6.2 大指标直接进去耄耋之时期

3.6.3 长期共存的目的将步向老时期

3.6.4 动态指标年龄剖断

3.6.5 空间分配作保

3.7 本章小结

第4章 虚构机质量监察和控制与故障管理工科具

4.1 概述

4.2 JDK的命令行工具

4.2.1 jps:设想机进度情状工具

4.2.2 jstat:虚拟机总结音讯监视工具

4.2.3 jinfo:Java配置新闻工具

4.2.4 jmap:Java内部存款和储蓄器印象工具

4.2.5 jhat:虚构机堆转储快速照相剖析工具

4.2.6 jstack:Java仓库追踪工具

4.2.7 HSDIS:JIT生成代码反汇编

4.3 JDK的可视化学工业具

4.3.1 JConsole:Java监视与管控台

4.3.2 VisualVM:多合一故障管理工科具

4.4 本章小结

第5章 调优案例深入分析与实战

5.1 概述

5.2 案例分析

5.2.1 高品质硬件上的主次安顿战略

5.2.2 集群间同步招致的内部存款和储蓄器溢出

5.2.3 堆外内部存款和储蓄器以致的溢出荒诞

5.2.4 外界命令招致系统缓慢

5.2.5 服务器JVM进度崩溃

5.2.6 不安妥数据布局招致内部存储器占用过大

5.2.7 由Windows设想内部存款和储蓄器招致的长日子暂停

5.3 实战:Eclipse运营速度调优

5.3.1 调优前的程序运营状态

5.3.2 进级JDK 1.6的品质变化及宽容难题

5.3.3 编写翻译时间和类加载时间的优化

5.3.4 调治内部存储器设置控污源搜罗频率

5.3.5 选取搜罗器裁减延迟

5.4 本章小结

其三部分 设想机施行子系统

第6章 类文件结构

6.1 概述

6.2 无关性的根本

6.3 Class类文件的组织

6.3.1 魔数与Class文件的本子

接收魔数来开展身份鉴定识别,值为:0xCAFFBABE(咖啡宝物)。设想机也一定要拒却实施超过其版本号的Class文件。

6.3.2 常量池

常量池能够精通为Class文件之中的资源客栈。

它是Class文件布局中也其余类型涉嫌最多的数据类型;
它也是据有Class文件空间最大的数量项目之一;
同临时候它依然在Class文件中率先个冒出表类型数码项目。

常量池首要贮存在两大类常亮:字面量(Literal)和标识引用(Symbolic
Reference)。

  • 字面量:相比较临近于Java语言层面的常量概念,如文本字符串、证明为final的常量值;
  • 标志援用:归于编写翻译原理方面包车型客车概念,包含上边三类常量:
  • [ ] 类和接口的全限制名
  • [ ] 字段的名号和陈述符
  • [ ] 方法的称呼和呈报符

字段和方法的号子援用,在运行期转换为实在的内部存款和储蓄器入口地址。设想机运维时,须求从常量池得到相应的标识援用,再在类创制时或运转时浅析、翻译到具体的内部存款和储蓄器地址之中。

6.3.3 访谈标志

常量池将来,就是看望标记(access_flags),那几个标记用于识别一下类依然接口档次的访谈新闻,包蕴:

  • 其一Class是类依旧接口;
  • 是还是不是定义为public类型;
  • 是或不是定义为abstract类型;
  • 倘若是类的话,是还是不是被声称为final等。

6.3.4 类索引、父类索引与接口索引会集

类索引和父索引是三个u2类型的数据(叁个类是一定要有一个父类。);而接口索引集合是一组u2项指标数目标集合(Java的多世袭正是经过接口来落到实处,几个类能够实现两个接口。)。入口的率先项数据为:接口流速计。那三项数据明确继续关系:类、父类、接口。
类索引、父索引->类或接口的暗号援用->具体的UTF-8编码的字符串(常量中的全节制名字符串)。

6.3.5 字段表集合

字段表:用于描述接口恐怕类中宣示的变量。字段富含类级变量以及实例级变量,但不蕴含在艺术内部宣称的一部分变量。能够包蕴的音讯有:

  • 字段的成效域(public、private、protect修饰符)
  • 是实例变量依然类变量(static修饰符)
  • 可变性(final)
  • 出现可以预知性(volatile修饰符,是还是不是强逼从主内部存款和储蓄器读写)
  • 是还是不是被种类化(transient修饰符)
  • 字段数据类型(基本项目、对象、数组)
  • 字段名称

次第修饰符都以布尔值,是用标记位来代表。
而字段叫什么名字、字段被定义为啥数据类型,那个都以无计可施牢固的,唯其如此援用常量池中的常量来说述。(具体变量的数据类型,引用常量池中的常量)

6.3.6 方法表集合

6.3.7 属性表集合

6.4 字节码指令简单介绍

6.4.1 字节码与数据类型

6.4.2 加载和仓库储存指令

6.4.3 运算指令

6.4.4 类型调换指令

6.4.5 对象创设与寻访指令

6.4.6 操作数栈管理指令

6.4.7 调控转移指令

6.4.8 方法调用和重返指令

6.4.9 万分管理指令

6.4.10 手拉手指令

6.5 公有设计和个人落成

6.6 Class文件构造的演化

6.7 本章小结

第7章 虚拟机类加运载飞机制

7.1 概述

设想机如何加载那些class文件?

虚构机把描述类的数码从Class文件加载到内部存款和储蓄器,并对数码举办校验改动深入分析初始化,最终变成能够被设想机直接行使的Java类型。——设想机的类加载机制。
Java语言里,类型的加载、连接和开端化进程都是在程序运转时期完成的,所以,给Java带来了动态增添的言语特色——都是依靠于运维期动态加载动态连接(迟绑定)的特点。

7.2 类加载的火候

类的生命周期:

加载->
(连接)验证->准备->解析->
初始化->
使用->
卸载。

加载、验证、打算、开头化和卸载那多少个阶段的各类是规定的,类的加载进程必须遵从这种顺序按部就班地初始,而浅析阶段则不自然:它在有个别意况下得以在初步化阶段之后再开头,那是为着援救Java语言的运行时绑定(也称为动态绑定或许中期绑定)。

如何动静下供给起头类加载进程的第一阶段:加载?

Java设想机规范中并从未实行强逼限制;可是对于初始化品级,设想机标准则是严俊规定了有且唯有5种情状不得不对类举办“初阶化”(而加载、验证、准备自然要求在此以前最初):

  1. 遇到new(实例化对象)、getstatic(读取类的静态字段)、putstatic(设置类的静态字段)或然invokestatic(调用类的静态方法)这4条字节码指令时,借使类未有开展过开头化,则需求先触发其初叶化。
    (被final修饰、已在编写翻译器把结果放入常量池的静态字段除此而外。)
  2. 接纳java.lang.reflect包的点子对类实行反射调用的时候,要是类未有实行过初步化,则须要先触发器起头化。
  3. 那个时候始化贰个类的时候,就算开采其父类还尚无开展过初叶化,则需求先触发器父类的最早化。
  4. 当虚构机运转时,客户必要钦赐三个要施行的主类(满含main(卡塔尔国方法的极度类),设想机就能够先开始化这一个主类。
  5. JDK
    1.7语言扶持,假如四个java.lang.invoke.MethodHandle实例最终的分析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,而且这一个法子句柄多对应的类未有开展过开端化,则必要先触发其早先化。

那多种场景中的行为称为对一个类实行了积极援用;除了那么些之外的,
不无援用类的方法都不会触发初步化,称为被动引用。

7.3 类加载的长河

7.3.1 加载

7.3.2 验证

7.3.3 准备

7.3.4 解析

7.3.5 初始化

7.4 类加载器

7.4.1 类与类加载器

将class文件字节码->内存->class对象作运营时数据的输入。

7.4.2 双亲委派模型

独有三种不用的类加载器:

  • 一种是运营类加载器(Bootstrap
    ClassLoader),那个类加载器使用C++语言完成,是设想机本人的一有个别;

  • 另一种正是抱有别的的类加载器,那些类加载器都有Java语言完结的,独立于虚构机外界,何况都三番五次抽象类java.lang.ClassLoader(加载字节码,找到定义的java类)。

  • [ ] 引导类加载器(Bootstrap ClassLoader):JAVA_HOMElib;

  • [ ] 扩张类加载器(Extension
    ClassLoader):JAVA_HOMElibext、java.ext.dirs钦点的具备类库;

  • [ ] 应用程序类加载器(Application
    ClassLoader):顾客类路径(ClassPath)所钦定的类库;

  • [ ] 自定义类加载器:文件加载器、网络加载器。

代办格局:交给其余类加载器,加载钦赐类。
父老妈委派机制:优先交给父加载器来加载。(为了安全,举个例子有人自定义了java.lang.Object,java.lang.String,制止主题类的自定义。)
雷同类被不一样加载器加载,JVM会感觉是区别的类。
汤姆cat服务器也是应用了代办形式:先品尝加载那些类,找不到再代理父类加载器,
与日常加载器顺序相反

7.4.3 破坏双亲委派模型

大人民委员会派模型现身过二次十分的大局面包车型大巴“被毁掉”意况:

  1. JDK 1.2事先,客商都以驾鹤归西袭java.lang.ClassLoader的当世无双目标就是为了
    重写loadClass()方法
    因为虚构机在举办类加载的时候会调用加载器的私有方法loadClassInternal(卡塔尔,而以此措施的并世无双逻辑正是去调用自个儿的loadClass(卡塔尔国
    JDK
    1.2随后才引进了二老委派模型,而类加载器和抽象类java.lang.ClassLoader则在JDK
    1.0一代就存在了。为了向前包容,JDK
    1.2事后的java.lang.ClassLoader加多了三个新的protect方法findClass()
  2. 父母委派格局本身的欠缺产生的——双亲委派模型很好地湮灭了一一类加载器的基础类的联结难点(越功底的类由越上层的加载器举办加载):底蕴类总是作为被客户代码调用的API。

只是功底类又要调用回顾客的代码,这该怎么做?
规范的例证正是:JNDI服务——它的代码由运维类加载器去加载(在JDK
1.3是放进去的rt.jar),
但是JNDI的目标正是对财富开展聚集管理和查找,它供给调用由独立商家达成并配置在应用程序的ClassPath下的JNDI接口提供者(SPI,瑟维斯Provider
Interface)的代码,但运营类加载器不容许“认知”那个代码啊!那该如何是好?

父阿娘委派模型行不通,为了解决这几个标题,引入了三个不太高雅的兼备:线程上下文类加载器(Thread
Context
ClassLoader)。这几个类加载器通过java.lang.Thread类的setContextLoader()主意开展设置。

  1. 由于客户对次第动态性的言情而引致——代码热替换(HotSwap)、模块热计划(Hot
    Deployment)等。

ODGi(Open Service Gateway Initivate卡塔尔国:面向java的动态模块系统。
A、B、C八个构件各自有投机的加载器(种种组件都有和好的加载器)。

7.5 本章小结

第8章 虚构机字节码实践引擎

8.1 概述

8.2 运维时栈帧构造

8.2.1 局地变量表

8.2.2 操作数栈

8.2.3 动态连接

8.2.4 方法重临地址

8.2.5 附加新闻

8.3 方法调用

8.3.1 解析

8.3.2 分派

8.3.3 动态类型语言帮衬

8.4 基于栈的字节码解释实行引擎

8.4.1 解释实施

8.4.2 基于栈的指令集与基于寄存器的指令集

8.4.3 基于栈的解释器试行进度

8.5 本章小结

第9章 类加载及施行子系统的案例与实战

9.1 概述

9.2 案例剖判

9.2.1 汤姆cat:正统的类加载器布局

9.2.2 OSGi:灵活的类加载器构造

9.2.3 字节码生成工夫与动态代理的贯彻

9.2.4 Retrotranslator:跨越JDK版本

9.3 实战:自身动手达成远程实行效劳

9.3.1 目标

9.3.2 思路

9.3.3 实现

9.3.4 验证

9.4 本章小结

第四部分 程序编写翻译与代码优化

第10章 早期(编译期)优化

10.1 概述

10.2 Javac编译器

10.2.1 Javac的源码与调整

10.2.2 拆解剖判与填充符号表

10.2.3 声明微机

10.2.4 语义深入分析与字节码生成

10.3 Java语法糖的意味

10.3.1 泛型与类型擦除

10.3.2 自动装箱、拆箱与遍历循环

10.3.3 条件编写翻译

10.4 实战:插入式表明微电脑

10.4.1 实战指标

10.4.2 代码达成

10.4.3 运营与测验

10.4.4 别的使用案例

10.5 本章小结

第11章 晚期(运行期)优化

11.1 概述

11.2 HotSpot设想机内的即时编写翻译器

11.2.1 解释器与编写翻译器

11.2.2 编译对象与触发条件

11.2.3 编译进度

11.2.4 查看及解析即时编写翻译结果

11.3 编写翻译优化才干

11.3.1 优化才能大概浏览

11.3.2 公共子表明式消释

11.3.3 数组边界检查灭绝

11.3.4 方法内联

11.3.5 逃逸解析

11.4 Java与CC++的编写翻译器相比

11.5 本章小结

第五有的 高效并发

第12章 Java内部存款和储蓄器模型与线程

12.1 概述

12.2 硬件的成效与一致性

12.3 Java内存模型

12.3.1 主内部存款和储蓄器与办事内部存储器

12.3.2 内部存储器间交互作用操作

12.3.3 对于volatile型变量的离奇法则

12.3.4 对于long和double型变量的新鲜法规

12.3.5 原子性、可以预知性与有序性

12.3.6 先行发生原则

12.4 Java与线程

12.4.1 线程的兑现

12.4.2 Java线程调整

12.4.3 状态转变

12.5 本章小结

第13章 线程安全与锁优化

13.1 概述

13.2 线程安全

13.2.1 Java语言中的线程安全

13.2.2 线程安全的得以达成格局

13.3 锁优化

13.3.1 自旋锁与自适应自旋

13.3.2 锁消除

13.3.3 锁粗化

13.3.4 轻量级锁

13.3.5 偏向锁

13.4 本章小结

附  录

附录A 编译Windows版的OpenJDK

附录B 设想机字节码指令表

附录C HotSpot虚构机首要参数表

附录D 对象查询语言(OQL)简要介绍

附录E JDK历史版本轨迹

发表评论

电子邮件地址不会被公开。 必填项已用*标注