|
| 1 | +jdk包含jre,jre包含jvm |
| 2 | +## ClassLoader |
| 3 | +ClassLoader(类加载器)是Java虚拟机(JVM)的一个重要组件,负责将字节码文件加载到内存中,以便在运行时创建Java类的实例。 |
| 4 | + |
| 5 | +ClassLoader的主要功能有: |
| 6 | + |
| 7 | +类的加载:ClassLoader从文件系统、网络或其他来源加载字节码文件,并将其转换为Java类的定义。加载的类可以在程序运行时动态使用。 |
| 8 | +类的链接:ClassLoader在加载类的过程中执行类的链接操作,包括验证、准备和解析。验证阶段检查类文件的合法性,准备阶段为静态变量分配内存并设置默认值,解析阶段将符号引用转换为直接引用。 |
| 9 | +类的初始化:ClassLoader负责对类进行初始化,包括执行静态初始化块和静态变量赋值。类的初始化在首次使用类时进行,保证类的初始化操作在多线程环境下的安全性。 |
| 10 | +ClassLoader具有层次结构,其中每个ClassLoader都有一个父ClassLoader。当加载类时,ClassLoader会先委托给父ClassLoader进行加载,只有在父ClassLoader无法加载时才会自行加载。这种层次结构的设计允许不同的ClassLoader加载不同的类,并且可以实现类似于模块化的隔离。 |
| 11 | +在使用ClassLoader加载字节码文件时,并不是直接拿到字节码文件去加载,而是通过ClassLoader提供的接口和方法来加载。ClassLoader提供了一系列方法,如loadClass()、findClass()、defineClass()等,用于加载字节码文件并生成对应的Java类。 |
| 12 | +需要注意的是,Java虚拟机规范并没有规定ClassLoader必须从字节码文件加载类,实际上ClassLoader可以从任何来源加载类,包括文件、网络、数据库等。这使得ClassLoader可以扩展为自定义的加载器,以满足特定的需求,例如动态加载插件、热部署等。 |
| 13 | + |
| 14 | +## JMM(Java Memory Model) |
| 15 | +JMM(Java Memory Model)将内存分为以下几个部分: |
| 16 | +主内存(Main Memory):主内存是Java程序中所有线程共享的内存区域。它存储了所有的变量、对象实例和数组等数据。主内存是所有线程可见的共享数据存储区域。 |
| 17 | +工作内存(Working Memory):工作内存是每个线程独立拥有的内存区域。每个线程都有自己的工作内存,用于存储线程执行过程中所需的数据副本。线程不能直接访问主内存,而是通过工作内存来读取和修改数据。 |
| 18 | +工作内存又可分为以下两种类型: |
| 19 | +a. 栈帧(Stack Frame):每个线程执行方法时,会为该方法创建一个栈帧,栈帧中存储了方法的局部变量、操作数栈等信息。每个线程的栈帧是独立的,用于支持方法的调用和执行。 |
| 20 | +b. 线程本地内存(Thread Local Memory):线程本地内存用于存储线程私有的数据,如线程的私有变量或使用ThreadLocal类存储的线程局部变量。线程本地内存对其他线程是不可见的。 |
| 21 | +JMM定义了对主内存和工作内存的访问规则和操作规则,以确保多线程程序的正确性和可见性。线程之间的通信和数据同步通过在主内存和工作内存之间进行数据的读取、写入和刷新来实现。 |
| 22 | +JMM规定了一套规则(如volatile关键字、synchronized关键字、锁等)来确保对共享变量的操作在多线程之间具有可见性、有序性和原子性,以避免出现并发访问的问题,如数据竞争、死锁等。通过JMM的规范,可以保证多线程程序在不同的硬件平台和操作系统上表现一致,提供了一种高层次的抽象来处理并发编程。 |
| 23 | + |
| 24 | +## 字符串常量池和运行时常量池 |
| 25 | +在Java中,有两个相关但不同的概念:运行时常量池(Runtime Constant Pool)和interned Strings(字符串常量池)。 |
| 26 | + |
| 27 | +运行时常量池(Runtime Constant Pool): |
| 28 | + |
| 29 | +运行时常量池是每个类或接口在加载到Java虚拟机中时所创建的一部分。 |
| 30 | +它包含了类或接口的常量池信息,包括字面量、符号引用和一些其他的常量。 |
| 31 | +运行时常量池在类加载后会存在于方法区(JDK 7之前)或元空间(JDK 8及更高版本)中。 |
| 32 | +运行时常量池中存储的常量是用于支持类的运行时行为的数据。 |
| 33 | +运行时常量池中的常量可以是各种类型,包括字符串、整数、浮点数、类和接口的符号引用等。 |
| 34 | + |
| 35 | +interned Strings(字符串常量池): |
| 36 | + |
| 37 | +字符串常量池是运行时常量池的一部分,用于存储字符串字面量。 |
| 38 | +字符串常量池是字符串对象的存储区域,存储了在代码中直接出现的字符串字面量。 |
| 39 | +字符串常量池使用了字符串驻留(String Interning)的机制,在运行时共享相同的字符串对象,以节省内存和提高性能。 |
| 40 | +当使用字符串字面量创建字符串对象时,如果字符串常量池中已经存在相同值的字符串对象,那么将返回该对象的引用;否则,将在字符串常量池中创建一个新的字符串对象,并返回其引用。 |
| 41 | +总结: |
| 42 | +运行时常量池是类加载过程中创建的常量池,包含了类或接口的常量信息。而字符串常量池是运行时常量池的一部分,用于存储字符串字面量,并通过字符串驻留机制实现字符串对象的共享。字符串常量池是运行时常量池中的一个特定部分,而运行时常量池还包含其他类型的常量 |
0 commit comments