JVM(一)类加载机制

本文详细介绍了JVM的内存结构,包括堆内存、方法区和栈,并深入解析了JVM类加载机制的三个阶段:加载、链接和初始化。通过具体示例展示了不同情况下类的初始化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)JVM内存结构主要有三大块:堆内存,方法区,栈

 

  • 堆内存 不连续的内存结构,是JVM管理的最大的内存结构。存放实例对象,是所有线程共享的。是垃圾回收器(gc)处理的主要区域,所以也叫gc堆
  • 方法区 存放代码,常量,类变量,里面包含常量池。一般会说方法区位于堆中。所以也被所有线程共享
  • 栈 物理内存连续的一块区域,是线程独有的,生命周期与线程相同,存放局部变量地址,指向堆,可以访问到堆
  • javac 命令将java程序经过编译生成.class文件

javac 命令将java程序经过编译生成.class文件

(二)java 调用JVM运行程序,其中JVM类加载机制分为3部分

 

 

 

 

  • 加载类   
  •    class字节码加载到内存中,将静态数据保存到方法区中,作为运行时数据结构,同时在堆中生成一个代表这个类的java.lang.Class对象,(这也就是为什么可以通过反射访问类信息)作为访问该类方法区中数据的入口。类加载器被调用。

 

  • 链接类 (将程序的二进制代码合并到JVM运行中)
  • 验证 验证类是否符合jvm规范
  • 准备 为static变量分配内存,设置初始值
  • 解析 常量池中的符号引用替换为直接引用(代码中只有变量或者常量符号,这个过程是给出每个变量,常量的地址)

 

  • 初始化

 

  • 执行类构造器<clinit>()方法的过程,由编译器自动收集类变量的赋值操作和static代码块,合并。先初始化父类变量。类构造器线程安全

如下图,是左边代码类加载以后,JVM内存图,在方法区形成运行时数据结构,生成Class对象,先是加载Demo01类,然后链接然后初始化。紧接着加载类A,在方法区形成A的运行时数据结构,以及Class对象,然后链接,为static变量分配内存,然后初始化,执行类构造器的<clinit>()方法,首先初始化width=100,然后执行static块,所以程序的输出为

静态初始化类A

创建A类对象

300

类加载完成后,就开始执行main方法,在栈中为main线程分配自己的栈内存,存入局部变量a=null,调用A的构造方法创建A的对象,存在堆中,这是a=A对象在堆中的地址

(三)详解JVM加载类的初始化

public class Demo01 {
static{
System.out.println("类Demo01的静态初始化块");
}
public static void main(String[] args) {
System.out.println("进入main方法");
A a=new A();
System.out.println(a.width);

}
}
class A_son extends A{
{
System.out.println("类A_son的静态初始化块");
}
}
class A extends A_father{
public static int width=80;
public final static int MAX=100;
static{
System.out.println("类A的静态初始化块");
}
public A(){
width=90;
System.out.println("类A的构造方法");
}
}
class A_father{
static{
System.out.println("类A_father的静态初始化块");
}

}

输出:首先加载类Demo01,执行他的静态块,进入main方法,出现A,加载A,首先初始化A的父类,执行A_father的static块,再初始化A,执行A的static块,最后调用构造方法,最后输出

(1)原程序只改变main方法:

public static void main(String[] args) {
System.out.println("进入main方法");
A a=new A();
System.out.println(a.width);
A a1=new A();
}

输出:类只被加载一次,因为用的是同一个加载器,所以JVM认为是同一个类

 

(2)原程序只改变main方法:

public static void main(String[] args) {
System.out.println("进入main方法");
System.out.println(A_son.width);

}

输出:通过A的子类A_son,访问A的静态变量,不会初始化A_son,静态域定义在哪个类中加载哪个类

 

(3)原程序只改变main方法:

public static void main(String[] args) {
System.out.println(A.MAX);

}

输出:访问类A的常量(比如final修饰)不会初始化类

 

(4)原程序只改变main方法:

public static void main(String[] args) {
System.out.println(A.width);

}

输出:访问类A的静态变量或方法会初始化类

 

(5)原程序只改变main方法:

public static void main(String[] args) {
Class s=Class.forName("xidian.lili.Demo01.Demo01");
Class s1=Class.forName("xidian.lili.Demo01.A");

}

输出:反射调用类,初始化

 

(6)原程序只改变main方法:

public static void main(String[] args) {
A[] a=new A[10];

}

输出:数组初始化调用。不会触发初始化

总结

类的主动引用

 

  • 加载类时,先加载父类(包括初始化)
  • new一个类的对象
  • 使用java.lang.Reflection包的方法进行调用
  • 先启动main方法所在的类

类的被动引用

  • 访问一个静态域(就是静态变量),只有真正定义这个静态域的类被初始化
  • 通过数组定义类引用,不会初始化
  • 引用类的常量不会触发类的初始化

 

### RTX 50显卡 PyTorch 配置指南 CUDA 版本要求 RTX 50显卡是基于NVIDIA的最新架构设计,支持更高的CUDA计算能力。为了确保PyTorch能够充分利用RTX 50显卡的性能,需要正确配置CUDA版本以及相关依赖库。以下是详细的配置指南和CUDA版本要求: #### 1. 确定CUDA版本 RTX 50显卡通常支持最新的CUDA版本(例如CUDA 12.x)。根据PyTorch官方文档和社区反馈[^1],建议使用与PyTorch兼容的最新CUDA版本。例如,PyTorch 2.3.0支持CUDA 12.1。如果需要更高版本的CUDA(如CUDA 12.2),可以参考社区提供的安装方法[^2]。 #### 2. 安装方式选择 对于RTX 50显卡,推荐以下两种安装方式: - **方案A:Conda安装** 使用Conda创建独立的Python环境,并安装PyTorch及相关依赖库。以下是具体命令: ```bash conda create -n pytorch_env python=3.10 conda activate pytorch_env conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia ``` 上述命令将安装PyTorch 2.3.0及CUDA 12.1的相关依赖[^1]。 - **方案B:Pip精确安装** 如果偏好使用pip安装,可以通过指定URL的方式下载对应版本的PyTorch及其依赖库。以下是安装示例: ```bash pip install torch==2.3.0+cu121 torchvision==0.18.0+cu121 torchaudio==2.3.0 --index-url https://download.pytorch.org/whl/cu121 ``` 如果需要更高版本的CUDA(如CUDA 12.2),请参考官方文档或社区提供的安装链接[^2]。 #### 3. 验证安装 完成安装后,可以通过以下代码验证PyTorch是否成功检测到GPU: ```python import torch print(torch.cuda.is_available()) # 应返回True print(torch.version.cuda) # 显示CUDA版本 print(torch.cuda.get_device_name(0)) # 显示GPU名称 ``` 如果`torch.cuda.is_available()`返回`False`,可能是因为CUDA未正确安装或驱动程序版本不匹配。 #### 4. 其他注意事项 - 确保NVIDIA驱动程序版本与CUDA版本兼容。例如,CUDA 12.x通常需要NVIDIA驱动程序版本530及以上。 - 如果遇到安装问题,可以参考PyTorch官方文档或社区讨论区。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值