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】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
115 0
【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意的 Offer
|
Java 知识图谱
Java中级工程师知识图谱
Java中级工程师知识图谱
96 0
Java中级工程师知识图谱
|
Java 知识图谱
java知识图谱
java知识图谱
266 0
java知识图谱
8张图带你轻松温习Java知识
年初四好,一图胜千言,下面图解均来自Program Creek 网站,目前它们拥有最多的票选。 如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟。 1
|
Java 算法 API
Java知识详细巩固_note2(数组_附demo code_其一为杨辉三角简析)
继 Java基础知识的全面巩固_note1(附各种demo code)拜读《核心技术卷》,笔记之。 提纲 1.1 for each循环1.2 数组初始化以及匿名数组1.
1086 0
|
8天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第11天】 在Java中,高效的并发编程是提升应用性能和响应能力的关键。本文将探讨Java并发的核心概念,包括线程安全、锁机制、线程池以及并发集合等,同时提供实用的编程技巧和最佳实践,帮助开发者在保证线程安全的前提下,优化程序性能。我们将通过分析常见的并发问题,如竞态条件、死锁,以及如何利用现代Java并发工具来避免这些问题,从而构建更加健壮和高效的多线程应用程序。
|
1天前
|
安全 Java
java多线程(一)(火车售票)
java多线程(一)(火车售票)
|
2天前
|
安全 Java 调度
Java并发编程:深入理解线程与锁
【4月更文挑战第18天】本文探讨了Java中的线程和锁机制,包括线程的创建(通过Thread类、Runnable接口或Callable/Future)及其生命周期。Java提供多种锁机制,如`synchronized`关键字、ReentrantLock和ReadWriteLock,以确保并发访问共享资源的安全。此外,文章还介绍了高级并发工具,如Semaphore(控制并发线程数)、CountDownLatch(线程间等待)和CyclicBarrier(同步多个线程)。掌握这些知识对于编写高效、正确的并发程序至关重要。
|
2天前
|
安全 Java 程序员
Java中的多线程并发编程实践
【4月更文挑战第18天】在现代软件开发中,为了提高程序性能和响应速度,经常需要利用多线程技术来实现并发执行。本文将深入探讨Java语言中的多线程机制,包括线程的创建、启动、同步以及线程池的使用等关键技术点。我们将通过具体代码实例,分析多线程编程的优势与挑战,并提出一系列优化策略来确保多线程环境下的程序稳定性和性能。
|
2天前
|
缓存 分布式计算 监控
Java并发编程:深入理解线程池
【4月更文挑战第17天】在Java并发编程中,线程池是一种非常重要的技术,它可以有效地管理和控制线程的执行,提高系统的性能和稳定性。本文将深入探讨Java线程池的工作原理,使用方法以及在实际开发中的应用场景,帮助读者更好地理解和使用Java线程池。