不懂这些核心,敢说你了解Java吗?

在JRE中,类加载器主要分为以下几种:

引导类加载器(Bootstrap)

它本身使用C/C++语言实现的,负责加载Java的核心类库,在jre\lib目录中,当中包括如rt.jar,这些都是Java自带的核心类库,必须由它来完成加载。

拓展/扩展类加载器(Extension)

这个加载器就是由Java语言实现,负责加载jre\lib\ext目录下的类库,这个目录下的类库都是一些扩展类。

应用程序/系统类加载器(Application)

这个类加载器同样使用Java语言实现,它主要负责加载classpath下面的所有类库,通常我们编写的Java类都是由这个类加载器完成加载。

三个类加载器的初始化过程:当程序运行时,首先会初始化引导类加载器,它就负责创建和初始化扩展类加载器,当扩展类加载器完成初始化之后,又负责创建和初始化系统类加载器。

这些类加载器协同起来完成整个类加载的过程,因此这些类加载器的加载模式是基于“双亲委托模型”。

举例说明

当我们编写一个Java类时,首先负责加载这个类的加载器是系统类加载器,但是它不会立马就去执行加载,而是先把这个任务交给父加载器(扩展类加载器),而扩展类加载器同样也会将这个任务交给父加载器(引导类加载器),最终当引导类加载器不能去加载这个类的时候(也就是在自己加载职责范围找不到的时候),又会将这个任务交回给子加载器。以此类推,最终我们编写的类都会配置在classpath环境中,所以,这个类的加载任务还是回到系统类加载器来完成。想了解更多加群学习656039503 java大神交流群 每天为你定时分享干货】

publicclassTest{

String name;

publicvoidsay(){

System.out.println("Hello Word");

}

// 程序的入口的方法,和具体类无关

publicstaticvoidmain(String[] args){

Test t =newTest();

t.say();

// 得到当前的类加载器ApplicationClassLoader

ClassLoader cl = Test.class.getClassLoader();

System.out.println(cl);

// 得到ApplicationClassLoader的父类加载器ExtensionClassLoader

ClassLoader extCl = cl.getParent();

System.out.println(extCl);

// 得到ExtensionClassLoader的父类加载器BootstrapClassLoader

// 由于BootstrapClassLoader是用C/C++语言编写的,在java中无法直接使用

// 所以才会返回一个null

ClassLoader bootCl = extCl.getParent();

System.out.println(bootCl);

}

}

当一个class文件最终加载到jvm之后,就表示类加载这个阶段已经全部完成。接下来就是对整个class文件的内容进行解析和做内存的分配。

内存分配

当JVM运行起来的时候就会给内存划分空间,那么这块空间称之为运行时数据区。

(备注:当一个

运行时数据区将划分为以下几块内容:

每一个线程运行起来的时候就会对应一个栈(线程栈),栈当中存放的数据是被当前线程所独有的。而栈当中存放的是栈帧,当线程调用一个方法的时候,就会形成一个栈帧,并将这个栈帧进行压栈操作,当方法执行完之后就会将这个栈帧进行出栈操作。这个栈帧里面包括(局部变量、操作数栈、指向当前方法对应类的常量池引用、方法的返回地址等信息)。

(备注:由于局部变量都是存放在栈中,而每一个线程都对应自己的线程栈,因此局部变量是线程安全的,不会才产生资源共享的情况。)

本地方法栈

本地方法栈的机制和栈的机制类似,区别在于,栈是运行Java所实现的方法,而本地方法栈是运行的本地方法(Native Method)。所谓的本地方法指的是在本地jvm中需要调用非Java语言所实现的方法,例如c语言。在JVM的规范中,其实没有强制性要求实现方一定要划分出本地方法栈的和具体的实现,这一部分可以根据实现方具体要求来实现。因此在HotSport虚拟机的实现中就将方法栈和本地方法栈二合为一。

程序计数器

程序计数器也可以称之为PC寄存器。它主要用于存放当前程序下一条将要执行的指令地址。CPU会根据这个地址找到对应的指令来执行。通俗的讲就是指令缓存。这个寄存器是有JVM内部实现的,并不是物理概念上的寄存器,但是JVM在实现功能的逻辑上是相同的。

堆内存中主要存放创建的对象以及数组。 堆内存是可以被多个线程所共享的一块区域,因此多个线程栈都可以去访问同一块堆的内存区域。堆里面的每一对象都存放了该实例的实例变量。

当在方法中定义了一个局部变量,如果这个变量是基本数据类型,那么这个变量的值就直接存放在栈中,如果这个变量是引用数据类型,那么这个对象变量就存放在堆内存中,而栈中存放的是一个指向堆内存中这个对象的首地址。

(备注:

引用

更改

数组

循环

实例变量和静态变量的区别:

实例变量:实例变量是随着对象的创建而创建,而实例是存放在堆中,所以实例变量自然也就跟实例一并保存在堆内存。只要创建多少个实例,就会有多少份实例变量。当实例被回收的时候,实例变量也随之而销毁。

静态变量:静态变量也叫类变量,它是在类加载的时候就已经初始化好,并存放在方法区,并且只有一份,所以它是被多个实例所共享的一个变量。

方法区

方法区在JVM中也是一个非常重要的一块内存区域,它和堆一样,是可以被多个线程所共享的一块区域。这个区域中主要存放了每一个加载的class文件信息。

在一个class文件中主要包含魔数(代码中出现但没有解释的数字常量或字符串)(用来确定是否是一个class文件)、常量池(常量池在下面会有完整说明)、访问标志(当前的class是类还是接口,是否是抽象类,

是否是public修饰,是否使用了final修饰等描述信息…)、字段表集合信息(使用什么访问修饰符、是实例变量还是静态变量,是否用final修饰等描述信息…)、

方法表集合信息(访问修饰符,是否静态方法,是否用final修饰,是否用了synchronized修饰,是否是native方法…)等内容。当一个类加载器加载一个class文件的时候,

会根据这个class文件的内容创建一个Class对象,而这个Class对象就包括了上述的这些内容。后续要创建这个类的所有实例,都是通过这个Class对象创建出来的。

常量池

常量池也是方法区中的一部分,它存放的内容是class文件中最重要的资源,JVM为每一个class对象都维护一个常量池。它主要存储两种类型的常量。

字面常量

字面常量通常就是在Java中定义的字面量值,如:int i =1,这个1就是字面量;String s = (“abc”),这个abc就是字面量。或者使用final修饰的常量值等等。

符号引用

符号引用主要包括类和接口的完整类名、属性字段的名称和描述符、方法名称和描述符等信息

在Java当中,8个基本数据类型都有对应的包装类型,而大部分包装类型都实现了常量池的技术,除了Double和Float类。

(备注说明:在JDK8之后,方法区已经取消,方法区被一个叫MetaSpace,它和堆合并到一起管理)

内存运行时数据区

扯了好多Java虚拟机的内容,也没讲多深,因为这里主要的目的是为了大家方便理解Java反射机制,下面正式进入正题

Class对象

当ClassLoader加载一个class文件到JVM的时候,会自动创建一个该类的Class对象,并且这个对象是唯一的,后续要创建这个类的任何实例,都会根据这个Class对象来创建。因此每当加载一个class文件的时候,都会创建一个与之对应的Class对象。

解析一个类的各个部分,形成一个对象。

外存中的类,加载到内存中,会形成该对象的Class类,例如:String类,加载到内存中,就是StringClass对象。

也就是说类是java.lang.Class类的实例对象,而Class是所有类的类

对于普通的对象,一般都的创建方式:

1String s =newString();

既然类都是Class的对象,那么能否像普通对象一样创建呢,当看源码时,是这样写的 :


privateClass(ClassLoader loader){

classLoader = loader;

}

喜欢文章的可以关注的我微信公众号:Java进阶高级    每天为你分享一段干货;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,531评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,157评论 11 349
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,620评论 0 11
  • 突然觉得管理者,其实是管理自己,再去影响别人。也就是上小学的时候就被教导的以身作则。把自己管好,立事修身正言,不用...
    Una笑笑阅读 280评论 0 0
  • 1.包装法##### 通过让图片完全符合作为“包装盒”的div得宽度,通过改变外层“包装盒”的宽度来达到图片自适应...
    一無月一阅读 254评论 0 0