类的加载时机

现在我们例子中生成的两个.class文件都会直接被加载到JVM中吗??

虚拟机规范则是严格规定了有且只有5种情况必须立即对类进行“初始化”(class文件加载到JVM中):

  • 创建类的实例(new 的方式)。访问某个类或接口的静态变量,或者对该静态变量赋值,调用类的静态方法
  • 反射的方式
  • 初始化某个类的子类,则其父类也会被初始化
  • Java虚拟机启动时被标明为启动类的类,直接使用java.exe命令来运行某个主类(包含main方法的那个类)
  • 当使用JDK1.7的动态语言支持时(....)

所以说:

  • Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存开销。

如何将类加载到jvm

class文件是通过类的加载器装载到jvm中的!

Java默认有三种类加载器:

各个加载器的工作责任:

  • 1)Bootstrap ClassLoader:负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
  • 2)Extension ClassLoader:负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
  • 3)App ClassLoader:负责记载classpath中指定的jar包及目录中class

工作过程:

  • 1、当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。
  • 2、当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。
  • 3、如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;
  • 4、若ExtClassLoader也加载失败,则会使用AppClassLoader来加载
  • 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

其实这就是所谓的双亲委派模型。简单来说:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上。

好处:

  • 防止内存中出现多份同样的字节码(安全性角度)

特别说明:

  • 类加载器在成功加载某个类之后,会把得到的 java.lang.Class类的实例缓存起来。下次再请求加载该类的时候,类加载器会直接使用缓存的类的实例,而不会尝试再次加载。

类加载详细过程

加载器加载到jvm中,接下来其实又分了好几个步骤:

  • 加载,查找并加载类的二进制数据,在Java堆中也创建一个java.lang.Class类的对象。
  • 连接,连接又包含三块内容:验证、准备、初始化。
  • 1)验证,文件格式、元数据、字节码、符号引用验证;
  • 2)准备,为类的静态变量分配内存,并将其初始化为默认值;
  • 3)解析,把类中的符号引用转换为直接引用
  • 初始化,为类的静态变量赋予正确的初始值。

JIT即时编辑器

一般我们可能会想:JVM在加载了这些class文件以后,针对这些字节码,逐条取出,逐条执行-->解析器解析。

但如果是这样的话,那就太慢了!

我们的JVM是这样实现的:

  • 就是把这些Java字节码重新编译优化,生成机器码,让CPU直接执行。这样编出来的代码效率会更高。
  • 编译也是要花费时间的,我们一般对热点代码做编译,非热点代码直接解析就好了。

热点代码解释:一、多次调用的方法。二、多次执行的循环体

使用热点探测来检测是否为热点代码,热点探测有两种方式:

  • 采样
  • 计数器

目前HotSpot使用的是计数器的方式,它为每个方法准备了两类计数器:

  • 方法调用计数器(Invocation Counter)
  • 回边计数器(Back EdgeCounter)。
  • 在确定虚拟机运行参数的前提下,这两个计数器都有一个确定的阈值,当计数器超过阈值溢出了,就会触发JIT编译。

回到例子中

按我们程序来走,我们的Java3yTest.class文件会被AppClassLoader加载器(因为ExtClassLoader和BootStrap加载器都不会加载它[双亲委派模型])加载到JVM中。

随后发现了要使用Java3y这个类,我们的Java3y.class文件会被AppClassLoader加载器(因为ExtClassLoader和BootStrap加载器都不会加载它[双亲委派模型])加载到JVM中

最后

如果对java微服务、分布式、高并发、高可用、大型互联网架构技术、面试经验交流。感兴趣的话可以关注我哦!

小编也有一些资料分享给大家,对学习提升很有作用的,有关于分布式,微服务,性能优化,Spring,MyBatis的等源码知识点的录像视频还有spring, jvm等等的面试题,希望能够帮助到大家!

需要的可以加我的JAVA交流群领取哦!

772300343  群主会主动给你的哒!

我是小架,我们下篇文章见!

Class文件和JVM的恩怨情仇的更多相关文章

  1. Docker与k8s的恩怨情仇(七)—— “服务发现”大法让你的内外交互原地起飞

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 第一章:Docker与k8s的恩怨情仇(一)-成为PaaS前浪的Cloud Foundry 第二章:Dock ...

  2. [你必须知道的.NET]第一回:恩怨情仇:is和as

    本文将介绍以下内 容: • 类型转换 • is/as操作符小议 1. 引言 类型安全是.NET设计之初重点考虑 的内容之一,对于程序设计者来说,完全把握系统数据的类型安全,经常是力不从心的问题.现在, ...

  3. CSS魔法堂:display:none与visibility:hidden的恩怨情仇

    前言  还记得面试时被问起"请说说display:none和visibility:hidden的区别"吗?是不是回答完display:none不占用原来的位置,而visibilit ...

  4. MSVC與CRT的恩怨情仇

    很久沒有寫程式設計入門知識的相關文章了,這篇文章要來談談程式庫 (Library) 連結,以及關於 MSVC 與 CRT 之間的種種恩怨情仇. 如果你使用的作業系統是 Linux.Mac 或其他非 W ...

  5. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  6. [拾 得]pipe和xargs的恩怨情仇

    Photo by Joshua Sortino on Unsplash   坚持知识分享,该文章由Alopex编著, 转载请注明源地址: http://www.cnblogs.com/alopex/  ...

  7. shell 脚本实战笔记(2)--环境变量PATH的恩怨情仇

    在linux环境下, 相信大家对环境变量PATH, 多多少少有所接触, 这边讲讲PATH的在linux的前世因缘. 先讲讲一个列子 假如我们在为一个新的应用配置其PATH路径中时,  不小心忽略了原先 ...

  8. 如何在IE11中开启WebGL暨微软和WebGL的恩怨情仇录

    正如我们上周报道的,国外开发者Francois Remy在泄露版Windows Blue附带的Internet Explorer 11中发现,WebGL接口已经封装完成,但功能上还未能开放支持.在这之 ...

  9. Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 大家在工作中或许或多或少都接触过Docker,那你知道Docker以及容器化背后的原理到底是什么吗? 容器化 ...

随机推荐

  1. 4-1-JS数据类型及相关操作

    js的数据类型 判断数据类型 用typeof   typeof "John"                 // alert(typeof "John") 返 ...

  2. python:html元素解析

    说明 主要是总结我通过python实现html解析的一个初步的思路和记录实现基础html解析的代码.本解析方式仅仅 只是实现了html按元素解析的功能,具体元素的分类获取还得需要再进行进一步的优化. ...

  3. Python用Pandas读写Excel

    Pandas是python的一个数据分析包,纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.Pandas提供了大量能使我们快速便捷地处理数据的函数和方法. Pandas官方文档 ...

  4. Oracle Merge Into 使用注意事项

    我们操作数据库的时候,有时候会遇到insertOrUpdate这种需求.如果数据库中存在数据就update,如果不存在就insert.Orcale数据库都提供了 MERGE  INTO 方法来处理这种 ...

  5. Python函数基础和函数参数

    函数的定义和函数的调用 return的作用 三种参数的定义 常用的内置函数 len() 函数基础 函数的定义 def 函数名(参数): pass return 表达式 pass在这里表示什么都没有,不 ...

  6. Nginx 配置实例-动静分离

    1.什么是动静分离  通过 location 指定不同的后缀名实现不同的请求转发.通过 expires 参数设置,可以使浏 览器缓存过期时间,减少与服务器之前的请求和流量.具体 Expires 定义: ...

  7. Linux-TCP之深入浅出send和recv【转】

    转自:https://www.cnblogs.com/JohnABC/p/7238417.html 内容摘自:TCP之深入浅出send和recv.再次深入理解TCP网络编程中的send和recv 建议 ...

  8. C学习笔记(5)--- 指针第二部分,字符串,结构体。

    1. 函数指针(function pointer): 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调 ...

  9. pwn-pwn2

    环境说明 Ubuntu 16.04 pwntool IDA gdb-peda 先丢到Ubuntu看看文件的类型  64位 然后看看保护机制,发现没有保护机制 然后丢到IDA看看  F5查看伪代码 ma ...

  10. 设计模式-单例模式(Singleton) (创建型模式)

    //以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Singleton.h #pragma once #include<iostream> class Sin ...