转载自 ---- http://lrysir.iteye.com/blog/1153226
这不是一篇描述jvm是什么的文章,也不介绍jvm跨平台的特性,也不是讲述jvm安全特性的文章,更不是讲解jvm指令操作,数据运算的文章, 本文重点讲述 类型的生命周期。
类型的生命周期涉及到: 类的装载、jvm体系结构、垃圾回收机制。
为什么要讲jvm体系结构? 因为类的装载和垃圾回收机制都和jvm体系结构息息相关。
那么什么是jvm体系结构呢?
当jvm运行起来的时候,它会向系统申请一片内存区(不同的jvm实现可能不同,有些可以使用虚拟内存),将这块内存分出一部分存储许多东西,例如:程序 创建的对象,传递给方法的参数,返回值,局部变量等等,我们将这块内存称之为“运行时数据区”, 运行时数据区可以划分成方法区、堆、java栈、pc寄存器、本地方法栈。
看到上面这幅图,和这些解说你可能大概的明白jvm 体系是个啥样子,但是你或许还不了解运行时数据区里面方法区等用来干嘛的。
那么现在你应该可以想象到一些jvm是怎么工作的了,是不是应该接着讲具体工作原理了呢?。但是不急,先了解下类的装载机制。
了解类的装载机制之前先了解jvm里面的类装载器:Bootstrap Loader、ExtClassLoader 、AppClassLoader;
ExtClassLoader (负责装载jre下面的rt.jar, charsets.jar)和AppClassLoader(负责转载classpath下面的类包)是ClassLoader(抽象类)的子类;
Bootstrap Loader(负责装载jre核心类库)是根装载器是c/c++写的在java里面看不到它。
这三个类装载器存在父子关系, 根装载器是 ExtClassLoader父装载器,ExtClassLoader是AppClassLoader父装载器;
Jvm中类的装载也是安全机制沙箱模型的第一道门槛。 Java装载类使用“双亲委派模式”—即全盘负责委托机制。
好现在让我们了解装载大概流程;
当装载一个类的时候,若是由用户指定一个类装载器装载的话,那么那个类装载器会先委派给父类装载器,一直委派到根装载器,如果装载的是一个 java.lang.String,由于它是核心类库的而且已经被装载过了,那么就会直接返回一个class对象,那么如果是一个根装载器找不到的类呢? 接着就会交给子类(下一级父类)装载器,如果还是没有找到类文件,接着就会由之前用户指定的那个类装载器装载。(这里没有说明装载超类的过程,请勿疏 忽)。
如果是有人恶意的写了一个基础类java.lang.String,那么会影响虚拟机吗? 不会因为这个类最终会交由根装载器装载,而根装载器只会去jre核心类库加载,最终返回的class类型并不是 用户写的String,而且系统自带的String,也就是说用户写String永远不会被加载。
了解了类装载器是怎么工作了之后,我们也需要了解下class文件格式;
The ClassFile Structure ClassFile{ u4 magic; //魔数 u2 minor_version; //class 次版本号 u2 major_version; //class 主版本号 u2 constant_pool_count; //常量池计数 cp_info constant_pool[constant_pool_count-1 ]; //常量池 u2 access_flags; //修饰符 u2 this_class; /常量池索引 u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attrributes_count]; }
我们需要了解的有很多,但是我们难以理解的就是 cp_info constant_pool 常量池;
一个常量池里面有很多表
CONSTANT_Utf8 UTF-8编码的Unicode字符串
CONSTANT_Integer int类型的字面值
CONSTANT_Float float类型的字面值
CONSTANT_Long long类型的字面值
CONSTANT_Double double类型的字面值
CONSTANT_Class 对一个类或接口的符号引用
CONSTANT_String String类型字面值的引用
CONSTANT_Fieldref 对一个字段的符号引用
CONSTANT_Methodref 对一个类中方法的符号引用
CONSTANT_InterfaceMethodref 对一个接口中方法的符号引用
CONSTANT_NameAndType 对一个字段或方法的部分符号引用
这些表结构我也不解释了
如果对class文件不够了解也没什么关系,知道个大概也行。那么我们了解了 jvm体系,类装载器工作流程,那么我们细看下 类装载器工作中 ,jvm运行时数据区的变化,方法区里面的结构等等。
在类装载的过程中, 每一个类装载器都会在方法区里面形成一张表,这张表记载着该装载器和对应的类的权限定名。没这么一张表就形成了jvm内部的命名空间。同时在方法区里面还该类的常量池等信息。
那么说到这些,其实这个过程还是很模糊,而且很多知识也落下了,那么我们现在看一个详细一点的装载过程。
当装载一个普通的类的时候,即调用类装载器的loadClass方法, 如果希望装载的类还没有被装载到命名空间,那么jvm会传递一个该类型的全限定名给类装载器,也就是常量池CONSTANT_Class_info(该表 存储着父类、类装载器等信息)入口的装载器,来试图装载被引用的类型,如果发起引用的类型是被jvm装载器定义的,那么由jvm类装载器装载,否则由用户 自定义装载器装载,那么一旦被引用的类型被装载了,jvm仔细检查它的二进制数据,如果类是是一个类,并且不是java.lang.Object。 jvm根据数据得到它的全限定名进行装载(递归的应用了)这个过程还需要递归超接口。
装载差不多讲完了,一个完整的过程 是: 装载—连接---初始化
那么连接和初始化就一带而过了, 重点放在垃圾回收。
连接的过程主要是验证(确认类型符合java语言的语义,并且它不会危及虚拟机的完整性)、准备(java 虚拟机为类变量分配内存,设计默认初始值)、解析(在类型的常量池中寻找类、接口、字段和方法的符合引用,把这些符号引用替换成直接引用的过程)。
初始化的时候,如果类存在直接超类,且超类还没有被初始化,就先初始化直接超类。初始化接口并不需要初始化它的父接口。
补充:
Jvm当运行某个方法的时候,先把这个方法压入java栈中,里面包含局部变量等信息,那么对象放入哪里呢? 压入栈的是对象的引用, 即变量, 所有的对象都存储在堆中。
为什么要把对象放入堆,把变量之类的数据放入栈呢? 说白了,对象太大了,存入栈中运算麻烦。(当然标准的回答不是这样的,我这里仅仅是说明实质)
了解了这么一个过程之后,我们必然要了解垃圾回收机制了。
基本回收算法
1. 引用计数:比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。
2. 标记-清除:此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。
3. 复制:此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每 次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现“碎片”问题。当然,此算法的缺点也是很明显的,就是 需要两倍内存空间。
4. 标记-整理:此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除 未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。
5. 增量收集:实施垃圾回收算法,即:在应用进行的同时进行垃圾回收。
6. 分代:基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法的。
相关推荐
通过以上对JVM原理和参数调优的深入学习,开发者可以更好地理解Java应用程序的运行机制,优化系统性能,解决可能出现的内存溢出、性能瓶颈等问题。本课程详细讲解了这些内容,无论你是初学者还是经验丰富的开发者,...
《Java实现的JVM——深入理解与实践》 在计算机科学领域,Java虚拟机(JVM)是Java语言的关键组成部分,它使得Java程序能够在不同平台上运行而无需重新编译。本项目“jvmjava”是一个开源项目,由Java语言实现,...
《实战JAVA虚拟机—JVM故障诊断与性能优化》是一本深入探讨Java虚拟机(JVM)技术的书籍,旨在帮助开发者和系统管理员诊断并优化JVM相关的性能问题。本书内容丰富,涵盖了大量的实践案例,使得即便是初学者也能理解...
### Java初学者必看:深入理解Java垃圾回收机制 对于Java初学者而言,理解Java的垃圾回收机制(Garbage Collection, GC)是非常重要的。在C++等其他编程语言中,程序员需要手动管理内存,比如使用new分配内存后,还...
本篇文章将从JVM的结构、内存模型、类加载机制以及垃圾收集等方面,帮助初学者快速入门JVM。 一、JVM结构 JVM主要由以下几个部分组成: 1. **类装载器(ClassLoader)**:负责加载.class文件,解析字节码并将其转换...
本资料包针对Java初学者,旨在介绍JVM的基础知识、工作原理以及如何在底层Java开发中有效地利用JVM。 一、JVM简介 Java虚拟机(JVM)是Java运行环境的一部分,它的主要任务是执行Java字节码。字节码是一种中间语言...
Java初学者必备基础教材主要涵盖了Java语言的核心概念和基本元素,是学习编程的入门路径。以下将详细解析这些知识点: 1. **Java语言与面向对象的程序设计**:Java是一种面向对象的语言,这意味着它强调通过类和...
Java虚拟机(JVM)规范和Java语言规范是Java开发者深入理解这个平台和技术的基石。这两部分规范分别定义了Java程序如何在JVM上运行以及Java编程语言的语法和语义。 《Java语言规范》(Java Language Specification...
这个压缩包“JAVA-JVM-全面/发展史/GC.zip”显然包含了关于Java、JVM、垃圾回收(GC)及其历史的深入学习资料,特别是通过“JAVA-笔记.pdf”这样的文档形式。 Java的发展史可以追溯到1991年,由Sun Microsystems的...
"java初学的一些小例子"这个主题,显然旨在帮助新手们通过实际操作来学习Java的核心概念。 首先,让我们深入了解一下Java的基础知识。Java程序设计语言由Sun Microsystems(现为Oracle公司)于1995年推出,其设计...
* 《深入理解 Java 虚拟机》:出自于 icyfenix 之手,可以作为了解 JVM 及 Java 内存管理的入门书籍。 * 《Java 虚拟机规范(Java SE 7 版)》:作者是 Java 编程语言的主要贡献者之一。如果你想系统、全面、深入的...
### Java虚拟机(JVM)结构基础详解 #### JVM概述与重要性 Java虚拟机(JVM)是Java技术的核心组成部分,负责执行Java字节码。...无论是初学者还是有经验的开发人员,深入了解JVM都是提升Java编程技能的重要途径之一。
这个全新的Java初学者实践教程将引导你逐步深入Java的世界,通过理论讲解和实例代码,使你在实践中学习和掌握编程技能。记住,实践是检验真理的唯一标准,只有不断动手编写代码,才能真正理解和掌握Java的精髓。祝你...
总的来说,Java语言规范和JVM规范是每个Java开发者深入学习的基石。通过研究这些文档,开发者不仅能理解语言的细节,还能掌握JVM的运行机制,从而编写出更高效、更稳定的代码。无论是初学者还是经验丰富的开发者,都...
Java虚拟机(JVM)是Java程序运行的核心组件,它为Java代码提供了跨平台的运行环境。本资源包含了两个PDF文件,分别详细介绍了JVM的基础和...因此,无论是初学者还是经验丰富的开发者,都应该对JVM有全面且深入的认识。
Java编程语言是全球广泛使用的开发语言之一,尤其适合初学者入门。这个“java学习资料初学java教程”压缩包提供了一系列资源,旨在帮助初学者掌握Java编程基础。 首先,Java是一种面向对象的语言,这意味着它强调将...
《Java深度历险》这本书是Java开发者...总之,《Java深度历险》涵盖了JVM的诸多方面,无论是初学者还是经验丰富的开发者,都能从中受益匪浅。通过深入学习,我们可以更好地理解和利用JVM,提升Java编程的效率和质量。
《深入Java虚拟机》(Inside the Java Virtual Machine) 是一本深入了解Java编程语言核心以及Java虚拟机(JVM)工作原理的经典书籍。这本书分为第一版和第二版,分别提供了当时最新的JVM技术解析。 首先,我们要了解...
《深入理解Java虚拟机++JVM高级特性与最佳实践1》这本书主要聚焦于Java虚拟机(JVM)的深入解析和实战应用,旨在帮助Java程序员更好地理解和优化Java应用程序的性能。作者周志明通过多年的实战经验和研究,将复杂的...
这个名为"java初学必做的实验"的资源显然旨在为新手提供一个系统化的学习路径,帮助他们从零开始逐步掌握Java编程。下面将详细阐述Java的基础知识,以及如何通过实践来加深理解。 首先,让我们从基础开始。Java是一...