您的位置:首页 >深入理解JavaSEJVM
发布于2026-08-06 阅读(0)
扫一扫,手机访问
JVM,全称Ja va虚拟机,是Ja va运行环境的核心。你可以把它想象成一台专门运行Ja va字节码的虚拟计算机,它的职责清晰:加载并运行字节码,提供运行时环境,管理内存和垃圾回收等。那么,JVM内部究竟是怎么组织的?它是如何加载类文件,又是怎样自动清理垃圾的?我们从最基础的区域划分说起。
JVM的设计思路很有意思——它直接模仿了真实操作系统的进程地址空间划分。毕竟,真实操作系统里,一个进程的地址空间被细分成了若干区域,JVM也就照葫芦画瓢,做了类似的区域划分。具体来说,有四个核心区域:
.class)。Ja va 8之前它叫方法区,后来改了个名。new 创建的对象。比如这句代码:Test t = new Test(),new Test() 一定在堆里,而 t 放在哪里?如果 t 是局部变量,就在栈;如果是成员变量,就在堆;如果是静态成员变量,就在元数据区。这一点需要特别留意。
一个类从磁盘上的 .class 文件变成内存中可用的类对象,需要经历三个步骤:
.class 文件,打开它,把文件内容读到内存中。这一步只是把原始字节码搬进来。.class 文件的内容是否合法,同时把合法内容转成结构化的数据。双亲委派模型描述的是类加载过程中,根据全限定类名找到 .class 文件的具体方式。JVM内部有专门的模块负责类加载,默认提供了三种类加载器,它们之间存在父子关系:
BootstrapClassLoader(爷):负责找Ja va标准库的目录。ExtensionClassLoader(爸):负责找Ja va扩展库的目录。ApplicationClassLoader(儿):负责找第三方库和当前项目的目录。过程是这样的:当需要加载一个类时,先从 ApplicationClassLoader 作为入口,但它不会直接去找,而是把加载任务交给父亲 ExtensionClassLoader;父亲又交给爷爷 BootstrapClassLoader。爷爷先在自己的范围内(Ja va标准库)找,找到了就加载,没找到就抛回给儿子;儿子再在自己的范围里找,如果还是没找到,最后就抛给 ApplicationClassLoader。如果连它都找不到,就抛出异常。这种层层委托的机制,有效地避免了类加载的冲突和重复加载。

Ja va中释放内存(主要是针对堆上的对象)的手段,就是垃圾回收。在C语言里,手动申请的内存需要手动释放,稍有不慎就会内存泄漏或野指针。Ja va引入了GC,让它自动识别哪些内存后续不会再被使用,然后自动释放。整个过程分为两步:找到垃圾,释放垃圾。
找到垃圾:有两种方案——引用计数和可达性分析。Ja va最终选择了可达性分析。
new 的时候,都搭配一个小的内存空间,保存一个整数,表示指向这个对象的引用个数。每次引用赋值都触发计数的修改,当计数为0时,这个对象就是垃圾。但这种方法有两个缺陷:一是内存消耗更多,二是可能出现循环引用——两个对象互相引用,但外部引用已经变空,计数却永远不会变为0,导致它们永远无法被回收。释放垃圾:有几种典型的算法,各有优劣。



售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8