JAVA知识

简介: 那么问题来了,JAVA为啥需要这么多类加载器(当然是多层负责每层对应的类系统,而且多态这个磨人的妖精很是厉害,需要多层加载机制进行处理。–个人理解)

__20180816171621

classloader
JVM装载


在说java的ClassLoader机制之前,我先了解下jvm的装载过程和其中的原理。
装载就是寻找一个类或者一个接口的二进制形式并且用二进制形式构造代表这个类或者是这个接口的class对象的过程。

类的生命周期是从被加载到虚拟机内存中开始,到卸载出内存结束。

加载->验证->准备->解析->初始化->使用->卸载


在java中,类装载器把一个类装入java虚拟机中,要经过三个步骤完成:装载、链接和初始化
这是java的装载流程,后面要说下java中,类的表现形式。

在java中,一个类代表着这个类要执行的代码,但是这个类可以有对应的各种不同的实例,不同的实例就是通过类中数据的表示状态来区分。状态是动态的,但是代码则不会。当我们将一个特定的状态和一个类对应起来,也就是意味着将一个类实例化。尽管相同的类呢,对应的实例有各种各样不同的状态,但是其基本底层还都是同一份代码,只是其中的数据状态有不同。jvm一般只加载一次类,以后相同的类就不会再加载。

QQ_20180808145905

下面就讲下JVM是如何区分不同的类的:

在Java中,一个类用其完全匹配类名(fully qualified class name)作为标识,这里指的完全匹配类名包括包名和类名。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类,被类加载器KlassLoader的一个实例kl1加载,Cl的实例,即C1.class在JVM中表示为(Cl, Pg, kl1)。这意味着两个类加载器的实例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它们所加载的类也因此完全不同,互不兼容的。

JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader。Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。

package javatest;
public class TestClassLoader{
    
    public static void main(String[] args){
    
        Class cl = null;
        ClassLoader cLoader;
        cLoader = ClassLoader.getSystemClassLoader();
        System.out.println(cLoader);
        while(cLoader != null){
    
            cLoader = cLoader.getParent();
            System.out.println(cLoader);
        }
        try{
    
            cl = Class.forName("java.lang.Object");
            cLoader = cl.getClassLoader();
            System.out.println("java.lang.Object loader is "+cl);
            cl = Class.forName("javatest.TestClassLoader");
            cLoader = cl.getClassLoader();
            System.out.println("LoadTest loader is "+cl);
        }catch(Exception e){
    
            e.printStackTrace();
        }
    }
}

output:
sun.misc.Launcher$AppClassLoader@73d16e93
// 系统的类装载器来自类sun.misc.Launcher$AppClassLoader@73d16e93的实例化,
sun.misc.Launcher$ExtClassLoader@15db9742
// 系统的类装载器的parent来自sun.misc.Launcher$ExtClassLoader@15db9742的实例化
null
//系统的类装载器的爷爷是由上面的Bootstrap ClassLoader实例而来,但是呢,这个Bootstrap ClassLoader是由C++实现的(嘿嘿嘿,混血儿),在java中是看不到滴。
java.lang.Object loader is null
//核心类都是由Bootstrap ClassLoader进行装载滴
LoadTest loader is sun.misc.Launcher$AppClassLoader@73d16e93
//用户自己的类都是由AppClassLoader进行加载滴。

QQ_20180808145745

那么问题来了,JAVA为啥需要这么多类加载器(当然是多层负责每层对应的类系统,而且多态这个磨人的妖精很是厉害,需要多层加载机制进行处理。–个人理解)

因为java是动态加载类的,这样的话,用到什么类就加载什么类,不用的就不加载(模仿Linux的内存管理机制!!!也让我想起了C++里面的内存申请,如果申请内存,先不分配实际物理内存,当需要访问的时候,再进行分配内存进行操作)

点击关注阿里云科技快讯,跟多精美礼品等你来拿!


QQ_20180808145709

参考:兔子哥哥

相关文章
|
Java 知识图谱
java知识图谱
java知识图谱
297 0
java知识图谱
|
存储 缓存 安全
【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
139 0
【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
|
Java 知识图谱
Java中级工程师知识图谱
Java中级工程师知识图谱
119 0
Java中级工程师知识图谱
8张图带你轻松温习Java知识
年初四好,一图胜千言,下面图解均来自Program Creek 网站,目前它们拥有最多的票选。 如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟。 1
|
Java 算法 API
Java知识详细巩固_note2(数组_附demo code_其一为杨辉三角简析)
继 Java基础知识的全面巩固_note1(附各种demo code)拜读《核心技术卷》,笔记之。 提纲 1.1 for each循环1.2 数组初始化以及匿名数组1.
1125 0
|
12天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
10天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
12天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
6天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
6天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
23 3