浅析类加载缓存机制

简介: 从上文我们分析了类加载器的过程与定义,我们从中得知,在JVM类加载器中有三大特性,其中缓存机制有效的保证了在同一个类加载器实例下,相同全名的类只加载一次,即loadClass方法不会被重复调用。我们这个小节就来看看它是如何利用缓存机制的已经它的流程是如何的。

前言

image.png
从上文我们分析了类加载器的过程与定义,我们从中得知,在JVM类加载器中有三大特性,其中缓存机制有效的保证了在同一个类加载器实例下,相同全名的类只加载一次,即loadClass方法不会被重复调用。我们这个小节就来看看它是如何利用缓存机制的已经它的流程是如何的。

源码定义

 protected final Class<?> findLoadedClass(String name) {
        if (!checkName(name))
            return null;
        return findLoadedClass0(name);
    }

private native final Class<?> findLoadedClass0(String name);

ClassLoader中的关于查询是否加载过类的方法也比较简单,在jdk1.8中使用的是直接内存,所以我们会用到直接内存进行缓存。这也就是我们的类变量为什么只会被初始化一次的由来。

缓存加载流程

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 类加载的并发控制锁,本期不展开
        synchronized (getClassLoadingLock(name)) {
            // 在直接内存中查找是否已经加载过此类。
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        // 父加载器不为空,委托给父类加载器
                        c = parent.loadClass(name, false);
                    } else {
                        // 如果父加载器为空,代表当前是启动类加载器。
                        // 注意启动类加载器是C++实现的,在java中是获取不到的
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    long t1 = System.nanoTime();
                    c = findClass(name);
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                // 它是当字节码加载到内存后进行链接操作,对文件格式和字节码验证,
                // 并为static字段分配空间并初始化,符号引用转为直接引用,访问控制,方法覆盖等等
                resolveClass(c);
            }
            return c;
        }
    }
目录
相关文章
|
3天前
|
存储 缓存 安全
第二章 HTTP请求方法、状态码详解与缓存机制解析
第二章 HTTP请求方法、状态码详解与缓存机制解析
|
4天前
|
存储 缓存 前端开发
HTTP的缓存机制是什么?
HTTP的缓存机制是什么?
34 1
|
4天前
|
缓存 Go API
Go 实现一个支持多种过期、淘汰机制的本地缓存的核心原理
本文旨在探讨实现一个支持多种 过期、淘汰 机制的 go 本地缓存的核心原理,我将重点讲解如何支持多样化的过期和淘汰策略。
83 0
|
3天前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
4天前
|
存储 消息中间件 缓存
redis的缓存机制
redis的缓存机制
102 0
|
4天前
|
存储 缓存 运维
【Docker 专栏】Docker 镜像的分层存储与缓存机制
【5月更文挑战第8天】Docker 镜像采用分层存储,减少空间占用并提升构建效率。每个镜像由多个层组成,共享基础层(如 Ubuntu)和应用层。缓存机制加速构建和运行,通过检查已有层来避免重复操作。有效管理缓存,如清理无用缓存和控制大小,可优化性能。分层和缓存带来资源高效利用、快速构建和灵活管理,但也面临缓存失效和层管理挑战。理解这一机制对开发者和运维至关重要。
【Docker 专栏】Docker 镜像的分层存储与缓存机制
|
4天前
|
缓存 NoSQL Java
17:缓存机制-Java Spring
17:缓存机制-Java Spring
41 5
|
4天前
|
存储 缓存 自然语言处理
深入PHP内核:探索Opcode缓存机制
【5月更文挑战第1天】 在动态语言如PHP的执行过程中,每次脚本被请求时都需要经过一系列复杂的解析和编译步骤。为了优化这一过程并提高性能,PHP引入了Opcode缓存机制。本文将详细探讨Opcode的概念、作用以及它如何显著提升PHP应用的执行效率。我们将从缓存原理出发,分析几种常见的Opcode缓存工具,并通过实例说明如何在实际项目中实现和优化缓存策略。
|
4天前
|
缓存 NoSQL PHP
【PHP开发专栏】PHP缓存机制与实现
【4月更文挑战第29天】本文介绍了PHP缓存的基本概念、策略及实现方式。PHP缓存包括应用缓存、Web服务器缓存、数据库缓存和分布式缓存,常见策略有缓存预热、更新和懒加载。PHP的缓存实现包括文件缓存、APC、OPcache、Memcached和Redis。最佳实践包括缓存热点数据、控制粒度、设置失效策略、保证一致性和确保安全性。文中还提供了一个新闻列表和详情页的缓存实战示例,帮助开发者理解如何在实际项目中应用缓存。
|
4天前
|
缓存 流计算
缓存命中率和过期机制的一般思路
【4月更文挑战第20天】缓存命中率是评估缓存效果的关键,目标是达到90%以上,但某些频繁的小请求场景可能无法实现。过期机制可采用定时删除(精确但开销大)、延迟队列(精确但有队列开销)、懒惰删除(简单但时间不精确)或定期删除(简单但性能损耗不可控)。
19 4