JVM知识点总结

Q:Java一次编译处处运行如何实现的

Java源码首先被编译成字节码(可以用javap指令查看字节码文件),再由不同平台的JVM进行解析,Java语言在不同的平台上运行时不需要进行重新编译,Java虚拟机在执行字节码的时候,把字节码转换成具体平台上的机器指令。
为什么这么做呢?
如果直接编译成字节码,每次执行都需要检查各种语法语义。
同时保证了兼容性,将别的语言解析成字节码。

Q:JVM如何加载class文件,JVM组成

JAM通过Class Loader将符合格式要求的class字节码文件加载到内存中,字节码文件中不同的类别的数据存储在内存不同的位置上。然后通过解释器对命令进行解析,并提交给操作系统去执行。
在这里插入图片描述
Class Loader:依据特定格式,加载class文件到内存
Execution Engine:对命令进行解析
Native Interface:融合不同开发语言的原生库为Java所用
Runtime Data Area: JVM内存空间结构模型

Q:Java反射

在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。

想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。

1. 获取字节码对象有3种方式:

		//第一种,forName()
        Class clazz = Class.forName("swap.Test");
        //第二种,class属性
        Class clazz2 = Test.class;
        //第三种,getClass()
        Test t = new Test();
        Class clazz3 = t.getClass();

2. 通过反射创建对象:

		//第一种,newInstance()
        Test test = (Test)clazz.newInstance();
        //第二种,通过默认或者指定的构造方法获取对象
        Constructor<Test> constructor = clazz.getDeclaredConstructor();
        Test test2 = constructor.newInstance();

3. 通过反射获取方法:

		//通过clazz的getDeclaredMethod获取到公有和私有方法,但是不能获取继承或实现接口的方法
        Method m1 = clazz.getDeclaredMethod("privateMethod",String.class);
        //私有方法设置true
        m1.setAccessible(true);
        m1.invoke(test,"Bob");
        //可以获取共有方法,继承或实现接口的方法,但是不能获取私有方法
        Method m2 = clazz.getMethod("publicMethod", String.class);
        m2.invoke(test,"Mike");

4. 通过反射获取属性:

		Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(test,"Alice");
        //或者声明Field[]获取多个属性
<think>好的,我现在需要回答用户关于JVM常用知识点总结的问题。根据用户提供的引用内容,我需要整理JVM的主要知识点,包括类加载、内存结构、垃圾回收和调优等方面。同时,用户还要求生成相关问题,所以我要确保覆盖这些方面的内容,并基于引用中的信息进行回答。 首先,我需要回顾用户提供的四个引用内容。引用[1]提到运行时数据区域,即JVM的内存结构。引用[4]详细列出了类加载、内存结构、垃圾回收和调优的各个子项,这可以作为回答的主要结构。引用[2]和[3]则涉及垃圾回收器的参数设置和工具使用,这部分需要整合到垃圾回收和调优部分。 接下来,我需要按照引用[4]的结构来组织回答:类加载篇、JVM内存结构篇、垃圾回收篇、JVM调优篇。每个部分下再分小点,比如类加载过程、类加载器分类、双亲委派机制等。同时,要确保使用正确的中文表达,并遵循系统级指令中的格式要求,例如数学表达式用$...$,独立公式用$$...$$,但根据用户的问题,可能数学公式较少,更多是技术术语。 在引用其他内容时,需要自然地添加引用标识,比如在提到内存结构时引用[1],在讨论堆内存溢出自动dump时引用[2],在说明GC日志和工具时引用[3],在整体结构上引用[4]。 然后,生成相关问题需要考虑用户可能感兴趣的后续问题,比如类加载机制、双亲委派的好处、内存结构各部分的作用、垃圾回收算法比较、调优工具使用等。需要确保问题覆盖用户可能想深入了解的方面,并基于已有的引用内容,避免超出范围。 最后,检查是否符合所有系统级指令:行内数学表达式是否正确(虽然这里可能用不上),独立公式是否单独成段(可能同样不适用),LaTeX语法正确,使用中文回答,生成相关问题,并在引用处标注标识符。同时,用户可见层要求结构清晰,帮助用户逐步解决问题,回答真实可靠。 总结步骤: 1. 按照引用[4]的结构组织内容,分为四个主要部分。 2. 每个部分下详细列出子项,结合其他引用的具体信息。 3. 在适当的位置添加引用标识,如内存结构引用[1],调优参数引用[2][3]。 4. 生成相关问题,覆盖各个主要部分的关键点。 5. 确保回答符合格式要求,无Markdown,使用中文,结构清晰。 现在开始撰写正式回答,确保每个部分简明扼要,信息准确,引用正确。</think>### JVM 常用知识点总结 #### 一、类加载篇 1. **类加载过程** 类加载分为 **加载、验证、准备、解析、初始化** 五个阶段。 - **加载**:通过类名获取二进制字节流,生成类的Class对象。 - **验证**:确保字节码符合JVM规范,例如文件格式、元数据、字节码验证[^4]。 - **准备**:为类变量分配内存并设置初始值(零值)。 - **解析**:将符号引用转换为直接引用。 - **初始化**:执行类构造器`<clinit>()`方法,完成静态变量赋值和静态代码块执行。 2. **类加载器分类** - **启动类加载器(Bootstrap ClassLoader)**:加载`JRE/lib`下的核心类库(如`rt.jar`)。 - **扩展类加载器(Extension ClassLoader)**:加载`JRE/lib/ext`目录的类。 - **应用程序类加载器(Application ClassLoader)**:加载用户类路径(ClassPath)的类。 - **自定义类加载器**:用户可通过继承`ClassLoader`实现自定义加载逻辑[^4]。 3. **双亲委派机制** 类加载时优先委派给父类加载器,若父类无法加载,子类才尝试加载。 **优点**:避免重复加载,保证核心类库的安全性。 --- #### 二、JVM内存结构篇 1. **JVM内存结构** JVM内存分为以下区域: - **堆(Heap)**:存储对象实例,是垃圾回收的主要区域[^1]。 - **方法区(Method Area)**:存储类信息、常量、静态变量。 - **虚拟机栈(VM Stack)**:存储方法调用的栈帧(局部变量表、操作数栈等)。 - **本地方法栈(Native Method Stack)**:为Native方法服务。 - **程序计数器(PC Register)**:记录当前线程执行的位置。 2. **对象的创建过程** 1. 类加载检查 → 2. 分配内存(指针碰撞或空闲列表) → 3. 初始化零值 → 4. 设置对象头 → 5. 执行`<init>`方法。 3. **强软弱虚引用** - **强引用**:对象存活时不会被回收。 - **软引用**:内存不足时可能被回收。 - **弱引用**:垃圾回收时立即被回收。 - **虚引用**:用于跟踪对象被回收的状态。 --- #### 三、垃圾回收篇 1. **如何判断对象是否死亡** - **可达性分析**:从GC Roots出发,不可达的对象标记为可回收。 - **引用计数法**(较少使用):循环引用可能导致内存泄漏。 2. **垃圾回收算法** - **标记-清除**:产生内存碎片。 - **复制算法**:适用于新生代(如Survivor区)。 - **标记-整理**:适用于老年代。 - **分代收集**:结合新生代(Minor GC)和老年代(Full GC)特性优化。 3. **常见垃圾收集器** - **Serial/Serial Old**:单线程,适合客户端应用。 - **ParNew**:多线程版Serial。 - **CMS(Concurrent Mark Sweep)**:以最短停顿时间为目标,但会产生内存碎片。 - **G1(Garbage-First)**:分Region回收,兼顾吞吐量和低延迟。 --- #### 四、JVM调优篇 1. **调优时机** - 频繁Full GC或长时间GC停顿。 - 堆内存溢出(可通过`-XX:+HeapDumpOnOutOfMemoryError`生成dump文件分析[^2])。 2. **监控与诊断工具** - **jps**:查看Java进程ID[^3]。 - **jstat**:监控GC状态(如`jstat -gc <pid>`)。 - **jstack**:生成线程快照,排查死锁。 - **jmap**:分析堆内存对象分布(如`jmap -histo <pid>`)。 3. **常用调优参数** - 堆大小:`-Xms`(初始堆)、`-Xmx`(最大堆)。 - 新生代比例:`-XX:NewRatio`。 - GC日志:`-XX:+PrintGCDetails -XX:+PrintGCTimeStamps`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值