`
liaokang.java
  • 浏览: 152190 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

java虚拟机基础知识

    博客分类:
  • java
阅读更多
1.java虚拟机与程序的生命周期
在如下几种情况下,java虚拟机将结束生命周期
a.执行了System.exit()方法
b.程序正常执行结束
c.程序在执行过程中遇到了错误或异常而异常终止
d.由于操作系统错误而导致java虚拟机进程终止

2.java虚拟机工作过程为加载,连接与初始化
加载:查找并加载类的二进制数据到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个Class对象,用来封装类在方法区类的数据结构

连接:将读入带内存的二进制数据合并到虚拟机的运行时环境中
a.验证:确保被加载类的正确性
1>类文件的结构检查
2>语义检查
3>字节码验证
4>二进制兼容性的验证
b.准备:为类的静态变量分配内存,并将其初始化为默认值
c.解析:把类中的符号引用转换为直接引用

初始化:把类中的静态变量赋予正确的初始值
a.假如这个类还没有被加载和连接,那么先加载和连接
b.假如这个类存在直接的父类,并且这个父类没有被初始化,先初始化直接的父类
c.假如类中存在初始化语句,依次执行这些初始化语句
d.当虚拟机初始化一个类时候要求所有父类已经被初始化,但这条规则不使用于接口,在初始化一个类时,并不会先初始化它所实现的接口
e.在初始化一个接口时,并不会先初始化它的父接口,只有当程序首次使用指定接口的静态变量时,才会导致该接口的初始化

3.java程序对类的使用方式可以分为主动使用和被动使用,所有的java虚拟机实现必须在每个类或者接口被java程序首席主动使用时才初始化他们,主动使用有以下几种情况,其它情况均为被动使用
a.创建类的实例
b.访问某个类或者接口的静态变量,或者对静态变量赋值
c.调用类的静态方法
d.反射
e.初始化一个类的子类
f.java虚拟机启动时被标明为启动类的类

4.java提供了两种类型的类加载器
a.java虚拟机自带的加载器
根类加载器(Bootstrap)
扩展类加载器(Extension)
系统类加载器(System)
b.用户自定义的类加载器
java.lang.ClassLoader的子类,用户可以自定义类的加载形式
java虚拟机规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的
过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误,如果这个类一直没有被程序主动使用,那么类加载器不会报告错误

5.类加载器
类加载器用来把类加载到java虚拟机中,从JDK1.2版本开始,类的加载器过程采用父亲委托机制,这种机制能更好保证java平台的安全,在此委托机制中,除了虚拟机自带的根类加载器以外,其余的类加载器都有且只有一个父类加载器

根类加载器:负责加载虚拟机的核心类库,如java.lang.*等,根类加载器的实现依赖于底层操作系统,它并没有继承java.lang.ClassLoader,因为它是用C++所写

扩展类加载器:它的父加载器为根类加载器,他从java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jre\lib\ext子目录下加载类库,如果用户把自己创建的jar放在该目录下也会由扩展加载器自动加载,它是纯java类,属于java.lang.ClassLoader的子类

系统类加载器:也成为应用加载器,它的父类加载器为扩展加载器,它从环境变量classpath或者系统属性path所指定的目录中加载类,他是用户自定义的类加载器的默认父加载器,它是纯java类,也是java.lang.ClassLoader的子类

每个类加载器都有自己的命名空间,命名空间由该加载器和其所有父类加载器所加载的类组成,在同一个命名空间中不会出现类的完整名字相同的两个类,在不同的命名空间中可以出现,同一个命名空间内的类是相互可见的,子加载器的命名空间包含所有父加载器的命名空间,所有子加载器加载的类能看见父加载器加载的类,但是父加载器不能看见子加载器加载的类

由同一类加载器加载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同,只有属于同一运行时包的类才能互相访问包可见的类和类成员,这样的限制能避免用户自定义的类冒充核心类库去访问核心类库的类和成员

下面是一个自定义加载器的小例子
首先是要被加载的两个类
public class Sample {
	public Sample() {
		System.out.println("Sample is loaded by:"
				+ this.getClass().getClassLoader());
		new Dog();
	}
}



public class Dog {
	public Dog(){
		System.out.println("Dog is loaded by:" + this.getClass

().getClassLoader());
	}
}


然后是自定义加载器
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {
	private String path = null;
	private String name = null;
	private String classType = ".class";

	public MyClassLoader(String name) {
		this.name = name;
	}

	public MyClassLoader(ClassLoader classLoader, String name) {
		super(classLoader);
		this.name = name;
	}
	
	@Override
	public String toString() {
		return this.name;
	}
	
	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public Class<?> findClass(String name) throws ClassNotFoundException {
		byte[] b = loadClassData(name);
		return defineClass(name,b,0,b.length);
	}

	public byte[] loadClassData(String name) {
		InputStream is = null;
		ByteArrayOutputStream baos = null;
		int ch = 0;
		byte[] data = null;
		try {
			is = new FileInputStream(new File(path+name+classType));
			baos = new ByteArrayOutputStream();
			while(-1 != (ch=is.read())){
				baos.write(ch);
			}
			data = baos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				is.close();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return data;
	}
	public static void main(String[] args) throws Exception {
		//定义loader1加载器,默认父加载器为系统加载器,并设置其加载目录
		MyClassLoader loader1 = new MyClassLoader("loader1");
		loader1.setPath("d:\\test\\serverlib\\");
		
		//定义loader2加载器,指定其父加载器为loader1,并设置其加载目录
		MyClassLoader loader2 = new MyClassLoader(loader1,"loader2");
		loader2.setPath("d:\\test\\clientlib\\");
		
		//定义loader3加载器,指定其父加载器为根类加载器,并设置其加载目

录
		MyClassLoader loader3 = new MyClassLoader(null,"loader3");
		loader3.setPath("d:\\test\\otherlib\\");
		
		testLoader(loader2);
		testLoader(loader3);
	}

	public static void testLoader(MyClassLoader loader) throws Exception {
		//将sample类加载进来,底层会调用findClass
		Class clazz = loader.loadClass("Sample");
		//对类的主动使用
		Object object = clazz.newInstance();
	}

}


在D盘新建对应的目录,当调用testLoader(loader2);时,由于父托管机制,它会先让loader1加载器去加载,而loader1的加载目录在d:\\test\\serverlib\\目录下,将Sample类和Dog类的.class文件放置该目录下,当调用testLoader(loader3);时,由于loader3的父类加载器为根类加载器,它不会对Sample和Dog进行加载,这时候只能由loader3加载器进行加载,而它加载的目录为d:\\test\\otherlib\\,将Sample类和Dog类的.class文件放置该目录下,最后将MyClassLoader.class文件放置在D盘根目录下,通过DOS窗口运行将会看到以下结果
Sample is loaded by:loader1
Dog is loaded by:loader1
Sample is loaded by:loader3
Dog is loaded by:loader3

分享到:
评论

相关推荐

    Java虚拟机笔记.pdf

    jvm的基础知识笔记,基本原理,内存分配,分析工具,以及常见的jvm参数优化。

    java面试题,内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点

    java面试题,内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。 优质的原创 Java 教程 全面清晰的 Java 学习路线 免费但靠谱的 Java 学习资料 精选的 Java 岗求职面试指南...

    JVM-Java虚拟机

    资源概要:JVM基础知识;类加载子系统;运行时数据区;对象的创建流程与内存分配; 对象内存布局;如何访问一个对象;GC基本原理;串行收集器;并行收集器; 能学到什么:1,JVM底层运行机制和原理;2JVM参数;3,...

    一份通俗易懂、风趣幽默的Java学习指南,内容涵盖Java基础、Java并发编程、Java虚拟机、Java企业级开发

    一份通俗易懂、风趣幽默的Java学习指南,内容涵盖Java基础、Java并发编程、Java虚拟机、Java企业级开发、Java面试等核心知识点.zip

    JAVA基础知识点总结

    以节约 编程时间 般认为 Java虚拟机是建立在实际的处理器基础上的 假想的计算机 Java虚拟机规范为Java虚拟机(JVM)作了 如下定义:在真实机器中用软件模拟实现的一种想象机器 Java虚拟机代码被存储在 class文件中;...

    Java常用基础知识-kaic.docx

    今天我们进入《Java常用基础知识》专题,动力节点Java资源库整合了近年各大厂的面试中的常见问题和知识点。每天更新10个,我们的最终目标就是大厂,若对题目有疑问,可在公众号后台留言提问。 目标:阿里巴巴、腾讯...

    深入java虚拟机第二版

    JVM虚拟基础知识介绍,很不错的一本书籍《深入java虚拟机第二版》。

    深入解析ANDROID虚拟机

    全书分为13个章节,分别讲解了Android系统的基础知识、Android系统的结构和核心框架、Java虚拟机和Dalvik虚拟机的知识、实现程序编译和调试、Dalvik的运作流程、DEX优化和安全管理、Android虚拟机生命周期管理和内存...

    java基础知识回顾.rar

    Java基础知识回顾 一:java概述 Java的三种技术架构 JAVAEE: Java Platform Enterprise Edition,开发企业环境下的应用程序,主要针对web程序开发; JAVASE: Java Platform Standard Edition,完成桌面应用程序...

    Java基础知识总结 - 超详细篇收藏.pdf

    2,JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库+JVM(java虚拟机)。 3,配置环境变量:让java jdk\bin目录下的工具,可以在任意目录下运行,原因是,将该工具所在目录告诉了系统,当...

    JAVA相关基础知识120问

    JAVA相关基础知识120问 1、面向对象的特征有哪些方面 ......... 2、String是最基本的数据类型吗? 基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,...

    Java零基础 - Java的可移植性.md

    在阅读本文之前,建议您具备以下基础知识: 对Java编程语言的基本语法和结构有一定的了解 理解面向对象编程的基本概念和思想 建议您在阅读过程中结合实践,尝试运行示例代码,加深对Java可移植性特点的理解,并提升...

    Java面试基础知识+中高级面试常见题目

    Java面试常见题目汇总概要主要针对Java语言的基础知识和中高级面试常见...除此之外,中高级面试中常见的题目还包括Java虚拟机、多线程、网络编程、分布式系统等方面的知识,以及实际项目中遇到的解决问题思路和方案等。

    JAVA核心面试知识整理-最全.zip

    Java核心面试知识整理包含Java基础,Java虚拟机,多线程并发,算法,各种Java中间件

    corejava基础重要知识点总结

    底层的功臣:JVM = java虚拟机 = 1 + 2 + 3 = 秘书 + 保镖 + 翻译 = 秘书 = 类加载器 = ClassLoader = 保镖 = 字节码校验器 = ByteCode Verifier = 翻译 = 解释执行器 = Interfreter 2:安全 健壮 电力 电信 ...

    java基础知识思考题+答案(个人整理)

    然后不同的硬件平台上安装有不同的Java虚拟机(JVM),由JVM来把字节码再“翻译”成所对应的硬件平台能够执行的代码。因此对于Java编程者来说,不需要考虑硬件平台是什么。所以Java可以跨平台。 3、 什么是Java语言的...

    java基础知识学习资料

     Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、简称API)构成。Java 应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展...

    深入理解java虚拟机的故障处理工具

    大家都知道在给系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。Java开发人员可以在jdk安装的bin目录下找到除了java,javac以外的其他命令。这些命令主要是一些用于监视虚拟机...

    java面向对象编程源码

    全书内容包括面向对象的编程思想、Java语言的基础知识、异常处理、类与对象的生命周期、多线程、Java集合、输入/输出和GUI编程等。其最大特色是以六条主线贯穿全书:面向对象编程思想、Java语言的语法、Java虚拟机...

Global site tag (gtag.js) - Google Analytics