java内存管理-java类加载器

wh6knrhe  于 2023-04-19  发布在  Java
关注(0)|答案(3)|浏览(93)

我是java的初学者,为了理解java内存管理,我阅读了Maaike货车Putten,Seán Kennedy写的《Java Memory Management》一书,我遇到了这样一句话:“为了能够执行应用程序,JVM大致有三个组件。一个是用来加载所有类的,类加载器。这实际上本身就是一个复杂的过程;加载类并验证字节码。
类加载器在字节码中验证什么(正如我阅读所有语法验证一样,访问验证是在生成字节码时完成的,而不是在生成和加载之后)可以解释类加载器试图在字节码中验证什么

piah890a

piah890a1#

我不知道这本书确定了其他两个组成部分,但我有一种强烈的感觉,这本书过度简化了事情,或者使用的术语与其他来源不同。
没有一个类装入器“用于装入所有的类”,而是任意数量的类。即使是最简单的设置也有三个类,

  • Bootstrap类加载器
  • 平台类加载器
  • 系统类加载器,也称为应用程序类加载器

类装入器的主要职责是定位类的定义,将其读入字节数组或ByteBuffer,并将其传递给JVM。JVM执行链接和验证。
在Java的第一个版本中,责任并没有像今天这样定义得那么好,因此当时的源代码或公然从这些过时的源代码复制的源代码仍然可能会告诉不同的事情。
当然,有人可能试图通过将Java执行环境划分为任意的概念组件来解释它,甚至使用与其他文档中使用的术语相冲突的名称。这不一定是错误的,但显然会在您试图将此解释与其他来源相匹配时引起混淆。
当您生成字节码时,例如通过编译源代码,字节码在理论上是正确和一致的,但有很强的理由在执行环境中不盲目信任字节码。

  • 不能保证执行环境中使用的所有组件(库或类)都是编译时使用的版本。类或库可能在使用它们的类或库编译后以不兼容的方式更改。
  • 不能保证所有涉及的工具(编译器或其他代码生成器)都没有错误
  • 可能存在对已编译代码的有意修改,以规避访问限制或以某种其他方式损害执行环境。

这更像是过去的问题,当小程序或Webstart应用程序,换句话说,从任意互联网源下载的代码应该与安全管理器一起运行时,是一件事。
在Java语言规范中给出了一个总结:

  • 验证 * 确保类或接口的二进制表示在结构上是正确的。例如,它检查每条指令是否有有效的操作码;每个分支指令分支到某个其他指令的开始,而不是分支到指令的中间;每个方法都有一个结构正确的签名;并且每个指令都遵守Java虚拟机的类型规则。

Java虚拟机规范中也有一章承认了上面给出的基本原理:
即使Java编程语言的编译器必须只生成满足前面章节中所有静态和结构约束的 class 文件,Java虚拟机也不能保证它被要求加载的任何文件都是由该编译器生成的或正确形成的。这些应用程序下载已经编译的 class 文件。浏览器需要确定 class 文件是由值得信赖的编译器生成的,还是由试图利用Java虚拟机的攻击者生成的。

  • 编译时检查的另一个问题是版本倾斜 *。
w51jfk4q

w51jfk4q2#

当Java程序执行时,类加载器负责将程序所需的类加载到JVM中。作为此过程的一部分,类加载器检查每个类的字节码,以确保它是Java类的有效和安全表示。
这个验证过程包括检查字节码的语法,以确保它符合Java语言的规则,以及验证字节码不包含任何安全漏洞或非法操作。
换句话说,类加载器检查字节码是否格式良好,是否遵守Java语言的规则,并确保字节码在JVM中执行是安全的。
在将程序代码转换为字节码时,而不是在JVM加载时,是否不会进行语法检查
Java代码的语法检查发生在编译过程中,当Java源代码转换为字节码时。在编译过程中,Java编译器执行语法检查,类型检查和其他验证,以确保生成的字节码有效并符合Java语言规范。
然而,由类加载器执行的字节码验证是在JVM将字节码加载到内存中时在运行时发生的附加步骤。该验证步骤确保字节码仍然有效并且符合Java语言规范。因为字节码可以在其生成之后被修改或篡改。字节码验证过程旨在检测字节码中的任何潜在错误或安全漏洞,当代码在JVM中执行时,这些错误或漏洞可能会导致问题。

vlju58qv

vlju58qv3#

验证在JVM规范的4.10节中有非常详细的描述。
https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.10

相关问题