JVM的小总结(转)

ref:http://www.cnblogs.com/ityouknow/p/6482464.html

  看了大神:纯洁的微笑的JVM系列篇,发现好多地方还是似懂非懂,理解的并不透彻,jvm的调优部分更是稀里糊涂;

  本片主要整理下jvm部分的知识点,方便以后的面试使用,(权且死记硬背了  !>_<!)

jvm的体系梳理

  • 类的加载机制
  • JVM的内存结构
  • GC算法 垃圾回收
  • GC分析 命令调优

底部给出思维导图参考

1、类的加载机制                                                                                                                                                                                          

  1.1:什么是类的加载:

    (1)将类的.class文件以二进制读入到内存,放入运行时数据区的方法区,然后在堆区创建一个java.lang.Class对象,以封装类在方法区的数据结构。

    (2)类加载的最终产品是位于堆区的Class对象,该Class对象封装类在方法区的数据结构,并向JAVA程序员提供了访问方法区内数据解耦的接口。

  1.2:类的生命周期:

 

####: 类的生命周期:

  #---- 类的加载

    |---- 装载(Loading)(为了区分加载,这里称其为装载):查找并导入类的Class文件,在堆区创建java.lang.Class的对象。

    |---- 连接过程分为三块:

      |---- 验证:文件的格式、元数据、字节码、符号引用验证,确保被装载的类的正确性,该阶段虽然重要但不是必须的;

      |---- 准备:为类的静态变量(static)分配内存,并将其初始化为默认值;如  public static int value=3 ,此时value的值是0而不是3;而对于:  public static final int value=3  ,该阶段value的值是3,而不是0,可以认为final static 常量在javac的编译期间,为value生成了ConstantValue属性,准备阶段jvm根据ConstantValue的值为value指定值。

      |---- 解析:将符号引用转换为直接引用;

     |---- 初始化:为类的静态变量,静态代码块等赋予正确的初始值。

   #---- 类的使用:new出对象供程序使用。

   #---- 类的卸载:执行垃圾回收。

    补充问题:

    1.2.1:JVM的初始化步骤(初始化过程):

    1. 假如这个类还没有被加载和连接,则程序先加载并连接该类; 
    2. 假如这个类的父类还没有被初始化,则先初始化其直接父类;
    3. 假如类中有初始化语句,则系统依次执行这些初始化语句。 

     1.2.2类的初始化时机:

    1. new创建类的实例时;
    2. 访问某个类或接口的静态变量,或者对该静态变量赋值;
    3. 调用类的静态方法;
    4. 反射(Class.forName("com.wht.Test"));
    5. 初始化某个类的子类时,父类也会进行初始化;
    6. JVM启动时被标明为启动类的类 

     1.2.3:哪几种情况下,JVM会结束生命周期: 

      1、执行了system.exit();

      2、程序正常结束;

      3、执行过程中发生异常或错误而终止;

      4、操作系统的错误导致JVM的进程终止;

   1.3:类加载器

    

    

  •   启动类加载器:Bootstrap ClassLoader,负责加载JDK\jre\lib目录下或被-Xbootclasspath指定位置处,可悲jvm识别的类库;
  •   扩展类加载器:Extension ClassLoader,负责加载JDK\jre\lib\ext目录下或由java.ext.dirs系统变量所指定路径中的所有类库;开发者可以直接使用该加载器;
  • 应用程序加载器:ApplicationClassLoader,负责加载用户类路径(Classpath)所指定的类,开发者可以直接使用该类加载器;

  类的加载机制:

  • 全盘负责:某个类加载器负责加载某个Class,对该Class所依赖和引用的其他Class都由该加载器负责加载,除非显示指定。  
  • 父类委托(双亲委托机制):某个类加载器收到Class加载请求时,现将该请求转至父类加载器,对Class进行加载,父类找不到该类无法完成加载,才尝试自己加载。
  • 缓存机制:所有加载过的Class都会被缓存,当程序中需要使用某个类时,类加载器先从缓存区寻找该Class,不存在,才会读取Class的二进制,生成Class对象存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效。

2、JVM内存结构                                                                   

    

方法区和堆是所有线程共享的内存区域;而java栈、本地方法栈和程序计数器是运行是线程私有的内存区域

 

  • 堆Heap:存放实例对象,是JVM内存中最大的一块,也是GC的主要区域。
      • 年轻代(8:1:1)
        • Eden空间
        • From Survivor空间
        • To Survivor空间  
      • 老年代 
  • 方法区Method Area:存放被jvm加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 程序计数器(Program Counter Register):是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。
  • 栈:
      • JVM栈:描述方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
      • 本地方法栈(Native Method Stacks):同JVM栈,只不过它是为JVM的Native方法服务;

对象分配规则:

  1. 对象优先分配在Eden区,  

                 

猜你喜欢

转载自www.cnblogs.com/whtblog/p/8999040.html