`

jvm原理

 
阅读更多

JVM是一个内存中的虚拟机,那它的存储就是内存了,我们写的所有类、常量、变量、方法都在内存中。JVM的组成部分

1)寄存器:用来存放系统状态,长度为32

2)栈:JVM是以栈为基本存储机制的处理机。对于每个类的每个存储方法,JVM都定义了一定的栈空间。包含以下信息:局部变量(记录各个方法局部变量的数组),执行环 境(当前方法栈的当前状态),操作栈(用来存储JVM指令参数的区域)

3)废区收集堆:所有的类被实例化时,所获得的存储空间都是从收集堆中分配的。此外,这个堆还要负责无用空间的回收使用。出于移植性和安全性考虑,Java不赋予程序设计员管理内存空间的权力。因而,在编译用new命令申请新对象存储空间后,由解释器负责跟踪记录这一块内存的使用情况。当使用结束时,回收空间送回堆中。

4)存储区和指令集

JVM功能:

ClassLoader类加载器

类加载器的作用是加载类文件(.class)到内存类加载的最终产品是位于运行时数据区的堆区的Class对象。Class对象封装了类在方法区内部的数据结构。并且向JAVA程序提供了访问类在方法区内的数据结构。


2.GC机制

1.为什么要使用垃圾收集?

在一个对象不再被程序引用时,它所占用的堆空间就可以回收。而且除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块,因为新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活对的对象之间,而请求分配新对象时可能不得不增大堆空间,因为虽然总的空闲空间是够的,但堆中没有连续的空闲空间放得下新对象。

上面是垃圾收集的作用,其好处在于:提高了工作效率,在一个没有垃圾收集机制的语言下编程,程序员还要花时间来解决难以捉摸的内存问题;帮助程序保持完整性,因为程序员不可能因为失误错误地释放内存而导致jvm崩溃;

2).垃圾收集器怎么知道对象不再被引用?

垃圾检测通常是通过建立一个根对象的集合并且检查从这些根对象开始的可触及性来实现。可触及就是正在执行的程序可以访问到的根对象和某个对象之间存在引用路径。区分活动对象和垃圾的两个基本方法是引用跟踪。

3).引用计数收集器是怎么判定对象为垃圾的?

的引用计数被置为1。当有其他变量被赋值为这个对象的引用时,计数加1;当这个对象的引用超过了生存期或被设置为新的值,计数减1;当计数为0时,对象被认为是垃圾,将被回收;这种方法的早已过时,主要缺陷是:他无法检测出循环引用(即两个或多个对象互相引用),例如:父对象有一个对子对象的引用,子对象又反过来引用父对象,这时计数永远不可能为0

4.)跟踪收集器又是怎么一回事?

跟踪就是对对象设置标记,通过一个从根结点开始的对象引用图追踪对象,在这个过程中对遇到的对象打上标记,当追踪结束时没有被打上标记的就是无法触及的,从而可以被回收。

5).怎么处理堆碎块?

一般处理堆碎块有以下几种收集器:

1.压缩收集器:把活动的对象都推到堆的一端,从而使另一端出瑞一个大的连续空闲区,所有被移动的对象的引用也被更新,指向新的位置;为了简便,更新被移动的对象引用时通过一个间接引用层,因为不直接引用堆中的对象而对象的引用实际上指向一个对象句柄表的话不用改变引用指向的位置,但损失了部分性能。

2.拷贝收集器把所有的活动的对象移动到一个新的区域,在这个过程中,活动对象被紧挨着布置从而消除原本它们在旧区域的空隙。一般的拷贝收集算法是——停止并拷贝,在这个方法中堆被分为两个区域,任何时候都只使用其的一个区域。对象在同一个区域分配,直到这个区域满了为止;这时程序中止,堆被遍历,遍历到的活动对象被拷贝到另外一个区域,完成后程序继续执行,如此循环;这种方法的代价是:对于指定大小的堆来说需两倍大小的内存。

3..按代收集的收集器

简单的停止拷贝收集器的缺点在于:第一次收集,所有的活动对象都要被拷贝,而程序中一般都有以下特点:

1大多数程序创建的大部分对象都具有很短的生命期;

2大多数程序都创建一些具有非常长生命周期的对象;

简单的停止拷贝收集器每次都把那些生命周期长的对象来回拷,浪费了时间;按代收集器通过把对象按照寿命来分组,更多的收集那些年幼的对象,当一个年幼对象经过几次收集后仍然存活,那就将它提升为寿命更高的一代,从而对这个对象的收集频率就减少了,帮命越长的收集频率就越小;

4.自适应收集器


JVM加载class文件的原理机制

  1.Java中的所有类,必须被装载到JMV中才能运行,这个装载工作是由JVM中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中。

  2.Java中的类大致分为三种:

  a)系统类

  b)扩展类

  c)由程序员自定义的类

  3.类装载方式,有两种:

  a)隐式装载,程序在运行过程中当碰到通过new等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。

  b)显式装载,通过class.forname()等方法,显式加载需要的类。

  4.类加载的动态性体现

  一个应用程序总是由n多个类组成,Java程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到JVM中,其它类等到JVM用到的时候再加载,这样的好处是节省了内存的开销。因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是Java动态性的一种体现。

  5Java类装载器

  Java中的类装载器实质上也是类,功能是把类载入JVM中,值得注意的是JVM的类装载器并不是一个,而是三个,层次结构如下:

BootstrapLoader-负责加载系统类
|
--ExtClassLoader-负责加载扩展类
|
--AppClassLoader-负责加载应用类

  为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型。

  6.类加载器之间是如何协调工作的

在这里Java采用了委托模型机制,这个机制简单来讲,就是类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent找不到,那么才由自己依照自己的搜索路径搜索类,注意喔,这句话具有递归性。




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics