Java review--JVM

来源:互联网 发布:一起作业网刷学豆软件 编辑:程序博客网 时间:2024/05/21 09:16


一、为什么使用虚拟机?

  Java的工作原理是这样的,通过IDE,在源码中定义不同的类,通过调用类的方法来访问系统资源,把源文件编译生成一种二进制中间码,存储到class文件中,通过运行与操作系统平台对应的虚拟机来运行class文件,执行编译后的字节码,调用class文件中实现的方法来满足程序中的Java API调用。

  虚拟机(Java Virtual Machine)的出现主要是为了解决Java跨平台特性的。


二、JVM与Java技术体系的关系


  Java技术体系包含Java程序设计语言、各种硬件平台Java虚拟机、Class文件格式、JavaAPI类库、来自商业机构和开源社区的第三方Java类库。

  JDK(Java Develpment Kit)包含Java程序设计语言、Java虚拟机、JavaAPI类库,是支持Java程序开发最小的环境。

  JRE(Java Runtime Environment)包含Java SE API子集和Java虚拟机,是支持Java程序运行的标准环境。


三、JVM的虚拟内存划分



  由图中可以看出,JVM主要包括这几个部分:类的加载,内存空间的分配,垃圾回收。


1.类加载器


虚拟机类加载机制

  把Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可被虚拟机直接使用的Java类型。

  加载器包含根类记载器(Bootstrap)、扩展类加载器(Extension)、系统类加载器(System)、用户自定义类加载器四种。类加载机制主要用到了全盘负责、宗亲委派、缓存机制。下面主要介绍一下宗亲委派原则


例如:

loader2——(委派)——>loader1——(委派)——>系统类加载器——(委派)——>扩展类加载器——(委派)——>根类加载器,

如果根类加载器和扩展类加载器不能加载,则系统类加载器加载,加载成功将  

Smaple引用——(传给)——>loader1——(传给)——>loader2;

如果系统类加载器也不能加载,则loader1尝试加载,不可以就loader2尝试加载,依然加载不成功,就报ClassNotFoundException异常。


类的加载生命周期

  类从被加载到虚拟机内存,到卸载出内存,整个生命周期如下:



加载:

  查找并加载类的二进制程序

连接:

  验证:确保被加载类的正确性和安全性。

  准备:正式为类变量分配内存并设置初始值,变量使用的内存在方法区分配。

  解析:把类中的符号引用转换为直接引用。


初始化:

1.创建类实例;

2.访问某个类或接口的静态变量,或者对该静态变量赋值;

3.调用类的静态方法;

4.反射(Class.forName("com.shengsiyuan.Test"));

5.初始化一个类的子类;

6. Java虚拟机启动时被标明为启动类的类。


卸载:

  虚拟机的生命周期进行中,始终不会被卸载。


2.内存空间的分配


程序计数器:

  当前线程执行的字节码的行号指示器。

  线程执行Java方法:计数器为虚拟机字节码指令地址。

  线程执行Native方法:计数器为空。


Java虚拟机栈:

  描述Java方法执行的内存模型。

  抛出异常:

   StackOverflowError:线程请求栈的深度>允许

   OutOfMemoryError:扩展到无法申请内存


Java本地方法栈:

  描述Native方法执行的内存模型。


堆:
  内存中最大。所有的对象实例以及数组都要在堆上分配。


方法区:

  虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。


运行时常量池:

  存放编译生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。


3.垃圾回收(Garbage Collection)


哪些内存需要回收?

  因为程序计数器、虚拟机栈、本地方法栈3个区域随线程而灭,栈中的栈帧随着方法的进入和退出而有条不紊的执行出栈和进栈。每个栈帧分配多少内存基本确定。内存的分配和回收都有一定的确定性,线程消亡后就自然回收了,所以不需要专门去回收。然而堆和方法区创建对象,方法啥的都是动态的,大小不一定。垃圾回收更加关注这部分的内存。


什么时候回收?



如何回收?


用什么收集器回收?


四、JVM性能优化

未完待续~~~








0 0
原创粉丝点击