当前位置: 首页 > news >正文

微信网页宣传网站怎么做扁平网站 文案

微信网页宣传网站怎么做,扁平网站 文案,云开发和普通开发区别,郑州seo外包收费标准第23讲 | 请介绍类加载过程#xff0c;什么是双亲委派模型#xff1f; Java 通过引入字节码和 JVM 机制#xff0c;提供了强大的跨平台能力#xff0c;理解 Java 的类加载机制是深入 Java 开发的必要条件#xff0c;也是个面试考察热点。 今天我要问你的问题是#xff0…第23讲 | 请介绍类加载过程什么是双亲委派模型 Java 通过引入字节码和 JVM 机制提供了强大的跨平台能力理解 Java 的类加载机制是深入 Java 开发的必要条件也是个面试考察热点。 今天我要问你的问题是请介绍类加载过程什么是双亲委派模型典型回答 典型回答 一般来说我们把 Java 的类加载过程分为三个主要步骤加载、链接、初始化具体行为在Java 虚拟机规范里有非常详细的定义。 首先是加载阶段Loading它是 Java 将字节码数据从不同的数据源读取到 JVM 中并映射为 JVM 认可的数据结构Class 对象这里的数据源可能是各种各样的形态如 jar 文件、class 文件甚至是网络数据源等如果输入数据不是 ClassFile 的结构则会抛出 ClassFormatError。 加载阶段是用户参与的阶段我们可以自定义类加载器去实现自己的类加载过程。 第二阶段是链接Linking这是核心的步骤简单说是把原始的类定义信息平滑地转化入 JVM 运行的过程中。这里可进一步细分为三个步骤 验证Verification这是虚拟机安全的重要保障JVM 需要核验字节信息是符合 Java 虚拟机规范的否则就被认为是 VerifyError这样就防止了恶意信息或者不合规的信息危害 JVM 的运行验证阶段有可能触发更多 class 的加载。 准备Preparation创建类或接口中的静态变量并初始化静态变量的初始值。但这里的“初始化”和下面的显式初始化阶段是有区别的侧重点在于分配所需要的内存空间不会去执行更进一步的 JVM 指令。 解析Resolution在这一步会将常量池中的符号引用symbolic reference替换为直接引用。在Java 虚拟机规范中详细介绍了类、接口、方法和字段等各个方面的解析。 最后是初始化阶段initialization这一步真正去执行类初始化的代码逻辑包括静态字段赋值的动作以及执行类定义中的静态初始化块内的逻辑编译器在编译阶段就会把这部分逻辑整理好父类型的初始化逻辑优先于当前类型的逻辑。 再来谈谈双亲委派模型简单说就是当类加载器Class-Loader试图加载某个类型的时候除非父加载器找不到相应类型否则尽量将这个任务代理给当前加载器的父加载器去做。使用委派模型的目的是避免重复加载 Java 类型。 考点分析 今天的问题是关于 JVM 类加载方面的基础问题我前面给出的回答参考了 Java 虚拟机规范中的主要条款。如果你在面试中回答这个问题在这个基础上还可以举例说明。 我们来看一个经典的延伸问题准备阶段谈到静态变量那么对于常量和不同静态变量有什么区别 需要明确的是没有人能够精确的理解和记忆所有信息如果碰到这种问题有直接答案当然最好没有的话就说说自己的思路。 我们定义下面这样的类型分别提供了普通静态变量、静态常量常量又考虑到原始类型和引用类型可能有区别。 public class CLPreparation {public static int a 100;public static final int INT_CONSTANT 1000;public static final Integer INTEGER_CONSTANT Integer.valueOf(10000); }编译并反编译一下 Javac CLPreparation.java Javap –v CLPreparation.class可以在字节码中看到这样的额外初始化逻辑 0: bipush 1002: putstatic #2 // Field a:I5: sipush 100008: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;11: putstatic #4 // Field INTEGER_CONSTANT:Ljava/lang/Integer;这能让我们更清楚普通原始类型静态变量和引用类型即使是常量是需要额外调用 putstatic 等 JVM 指令的这些是在显式初始化阶段执行而不是准备阶段调用而原始类型常量则不需要这样的步骤。 关于类加载过程的更多细节有非常多的优秀资料进行介绍你可以参考大名鼎鼎的《深入理解 Java 虚拟机》一本非常好的入门书籍。我的建议是不要仅看教程最好能够想出代码实例去验证自己对某个方面的理解和判断这样不仅能加深理解还能够在未来的应用开发中使用到。 其实类加载机制的范围实在太大我从开发和部署的不同角度各选取了一个典型扩展问题供你参考 如果要真正理解双亲委派模型需要理解 Java 中类加载器的架构和职责至少要懂具体有哪些内建的类加载器这些是我上面的回答里没有提到的以及如何自定义类加载器 从应用角度解决某些类加载问题例如我的 Java 程序启动较慢有没有办法尽量减小 Java 类加载的开销 另外需要注意的是在 Java 9 中Jigsaw 项目为 Java 提供了原生的模块化支持内建的类加载器结构和机制发生了明显变化。我会对此进行讲解希望能够避免一些未来升级中可能发生的问题。 知识扩展 首先从架构角度一起来看看 Java 8 以前各种类加载器的结构下面是三种 Oracle JDK 内建的类加载器。 启动类加载器Bootstrap Class-Loader加载 jre/lib 下面的 jar 文件如 rt.jar。它是个超级公民即使是在开启了 Security Manager 的时候JDK 仍赋予了它加载的程序 AllPermission。 对于做底层开发的工程师有的时候可能不得不去试图修改 JDK 的基础代码也就是通常意义上的核心类库我们可以使用下面的命令行参数。 # 指定新的bootclasspath替换java.*包的内部实现 java -Xbootclasspath:your_boot_classpath your_App# a意味着append将指定目录添加到bootclasspath后面 java -Xbootclasspath/a:your_dir your_App# p意味着prepend将指定目录添加到bootclasspath前面 java -Xbootclasspath/p:your_dir your_App用法其实很易懂例如使用最常见的 “/p”既然是前置就有机会替换个别基础类的实现 我们一般可以使用下面方法获取父加载器但是在通常的 JDK/JRE 实现中扩展类加载器 getParent() 都只能返回 null。 public final ClassLoader getParent()扩展类加载器Extension or Ext Class-Loader负责加载我们放到 jre/lib/ext/ 目录下面的 jar 包这就是所谓的 extension 机制。该目录也可以通过设置 “java.ext.dirs”来覆盖。 java -Djava.ext.dirsyour_ext_dir HelloWorld应用类加载器Application or App Class-Loader就是加载我们最熟悉的 classpath 的内容。这里有一个容易混淆的概念系统System类加载器通常来说其默认就是 JDK 内建的应用类加载器但是它同样是可能修改的比如 java -Djava.system.class.loadercom.yourcorp.YourClassLoader HelloWorld如果我们指定了这个参数JDK 内建的应用类加载器就会成为定制加载器的父亲这种方式通常用在类似需要改变双亲委派模式的场景。 具体请参考下图 至于前面被问到的双亲委派模型参考这个结构图更容易理解。试想如果不同类加载器都自己加载需要的某个类型那么就会出现多次重复加载完全是种浪费。 通常类加载机制有三个基本特征 双亲委派模型。但不是所有类加载都遵守这个模型有的时候启动类加载器所加载的类型是可能要加载用户代码的比如 JDK 内部的 ServiceProvider/ServiceLoader机制用户可以在标准 API 框架上提供自己的实现JDK 也需要提供些默认的参考实现。 例如Java 中 JNDI、JDBC、文件系统、Cipher 等很多方面都是利用的这种机制这种情况就不会用双亲委派模型去加载而是利用所谓的上下文加载器。 可见性子类加载器可以访问父加载器加载的类型但是反过来是不允许的不然因为缺少必要的隔离我们就没有办法利用类加载器去实现容器的逻辑。 单一性由于父加载器的类型对于子加载器是可见的所以父加载器中加载过的类型就不会在子加载器中重复加载。但是注意类加载器“邻居”间同一类型仍然可以被加载多次因为互相并不可见。 在 JDK 9 中由于 Jigsaw 项目引入了 Java 平台模块化系统JPMSJava SE 的源代码被划分为一系列模块。 类加载器类文件容器等都发生了非常大的变化我这里总结一下 前面提到的 -Xbootclasspath 参数不可用了。API 已经被划分到具体的模块所以上文中利用“-Xbootclasspath/p”替换某个 Java 核心类型代码实际上变成了对相应的模块进行的修补可以采用下面的解决方案 首先确认要修改的类文件已经编译好并按照对应模块假设是 java.base结构存放 然后给模块打补丁 java --patch-module java.baseyour_patch yourApp扩展类加载器被重命名为平台类加载器Platform Class-Loader而且 extension 机制则被移除。也就意味着如果我们指定 java.ext.dirs 环境变量或者 lib/ext 目录存在JVM 将直接返回错误建议解决办法就是将其放入 classpath 里。 部分不需要 AllPermission 的 Java 基础模块被降级到平台类加载器中相应的权限也被更精细粒度地限制起来。 rt.jar 和 tools.jar 同样是被移除了JDK 的核心类库以及相关资源被存储在 jimage 文件中并通过新的 JRT 文件系统访问而不是原有的 JAR 文件系统。虽然看起来很惊人但幸好对于大部分软件的兼容性影响其实是有限的更直接地影响是 IDE 等软件通常只要升级到新版本就可以了。 增加了 Layer 的抽象 JVM 启动默认创建 BootLayer开发者也可以自己去定义和实例化 Layer可以更加方便的实现类似容器一般的逻辑抽象。 结合了 Layer目前的 JVM 内部结构就变成了下面的层次内建类加载器都在 BootLayer 中其他 Layer 内部有自定义的类加载器不同版本模块可以同时工作在不同的 Layer。 谈到类加载器绕不过的一个话题是自定义类加载器常见的场景有 实现类似进程内隔离类加载器实际上用作不同的命名空间以提供类似容器、模块化的效果。例如两个模块依赖于某个类库的不同版本如果分别被不同的容器加载就可以互不干扰。这个方面的集大成者是Java EE和OSGI、JPMS等框架。 应用需要从不同的数据源获取类定义信息例如网络数据源而不是本地文件系统。 或者是需要自己操纵字节码动态修改或者生成类型。 我们可以总体上简单理解自定义类加载过程 通过指定名称找到其二进制实现这里往往就是自定义类加载器会“定制”的部分例如在特定数据源根据名字获取字节码或者修改或生成字节码。 然后创建 Class 对象并完成类加载过程。二进制信息到 Class 对象的转换通常就依赖defineClass我们无需自己实现它是 final 方法。有了 Class 对象后续完成加载过程就顺理成章了。 具体实现我建议参考这个用例。 (https://www.baeldung.com/java-classloaders) 我在专栏第 1 讲中就提到了由于字节码是平台无关抽象而不是机器码所以 Java 需要类加载和解释、编译这些都导致 Java 启动变慢。谈了这么多类加载有没有什么通用办法不需要代码和其他工作量就可以降低类加载的开销呢 这个可以有。 在第 1 讲中提到的 AOT相当于直接编译成机器码降低的其实主要是解释和编译开销。但是其目前还是个试验特性支持的平台也有限比如JDK 9 仅支持 Linux x64所以局限性太大先暂且不谈。 还有就是较少人知道的 AppCDSApplication Class-Data SharingCDS 在 Java 5 中被引进但仅限于 Bootstrap Class-loader在 8u40 中实现了 AppCDS支持其他的类加载器在目前 2018 年初发布的 JDK 10 中已经开源。 简单来说AppCDS 基本原理和工作过程是 首先JVM 将类信息加载 解析成为元数据并根据是否需要修改将其分类为 Read-Only 部分和 Read-Write 部分。然后将这些元数据直接存储在文件系统中作为所谓的 Shared Archive。命令很简单 Java -Xshare:dump -XX:UseAppCDS -XX:SharedArchiveFilejsa \-XX:SharedClassListFileclasslist -XX:SharedArchiveConfigFileconfig_file第二在应用程序启动时指定归档文件并开启 AppCDS。 Java -Xshare:on -XX:UseAppCDS -XX:SharedArchiveFilejsa yourApp通过上面的命令JVM 会通过内存映射技术直接映射到相应的地址空间免除了类加载、解析等各种开销。 AppCDS 改善启动速度非常明显传统的 Java EE 应用一般可以提高 20%~30% 以上实验中使用 Spark KMeans 负载20 个 slave可以提高 11% 的启动速度。 与此同时降低内存 footprint因为同一环境的 Java 进程间可以共享部分数据结构。前面谈到的两个实验平均可以减少 10% 以上的内存消耗。 当然也不是没有局限性如果恰好大量使用了运行时动态类加载它的帮助就有限了。 今天我梳理了一下类加载的过程并针对 Java 新版中类加载机制发生的变化进行了相对全面的总结最后介绍了一个改善类加载速度的特性希望对你有所帮助。 一课一练 关于今天我们讨论的题目你做到心中有数了吗今天的思考题是谈谈什么是 Jar Hell 问题你有遇到过类似情况吗如何解决呢 请你在留言区写写你对这个问题的思考我会选出经过认真思考的留言送给你一份学习奖励礼券欢迎你与我一起讨论。 可以减少 10% 以上的内存消耗。 当然也不是没有局限性如果恰好大量使用了运行时动态类加载它的帮助就有限了。 今天我梳理了一下类加载的过程并针对 Java 新版中类加载机制发生的变化进行了相对全面的总结最后介绍了一个改善类加载速度的特性希望对你有所帮助。 一课一练 关于今天我们讨论的题目你做到心中有数了吗今天的思考题是谈谈什么是 Jar Hell 问题你有遇到过类似情况吗如何解决呢 请你在留言区写写你对这个问题的思考我会选出经过认真思考的留言送给你一份学习奖励礼券欢迎你与我一起讨论。 你的朋友是不是也在准备面试呢你可以“请朋友读”把今天的题目分享给好友或许你能帮到他。
http://www.w-s-a.com/news/811220/

相关文章:

  • 湖南省建设厅城乡建设网站怎么建立一个网站网址
  • 图书馆网站建设的规章制度免费个人主页注册
  • 表格网站源码wordpress更换网站域名
  • 芜湖做网站多少钱做公司的网站的需求有哪些
  • 玉溪网站建设制作凌风wordpress百度云
  • 专业建网站价格门户网站建设 请示
  • 安徽省省博物馆网站建设佛山公司网站设计
  • 温州专业营销网站公司网络建设规划
  • 做模型常说的d站是什么网站wordpress 繁體
  • 给网站做h5缓存机制获取小程序api
  • 网站开发文档东莞市建设网站首页
  • 公共空间设计网站企业门户网站建设教程
  • 网站建设公司 深圳镇江建设质量监督站网站
  • 网站底部版权怎么做软广告经典案例
  • 网站收录突然全部没有了东莞网站建设公司电话
  • 境外企业网站推广免费ppt元素
  • 2018网站建设行业广东网站seo
  • 网站后台加密云服务器2008做网站
  • dw制作一个环保网站模板下载吉安网站建设收费
  • 深圳珠宝网站设计北京高端网站建设优势
  • 合肥企业制作网站wordpress创建网站
  • 织梦网站开发兼职wordpress 中间截取缩略图
  • 南通制作网站旅游搭建网站
  • 专业做商铺的网站个人网页html模板完整代码
  • 什么网站做美食最好最专业关键词推广是什么意思
  • 自助建设网站软件网站导航网站可以做吗
  • 网站模板放哪长沙网站优化分析
  • 泉州网站建设价钱网站模板素材
  • 南通网站托管js建设网站外网
  • 成都企业网站公司wordpress内页模板