zoukankan      html  css  js  c++  java
  • java-jvm类加载-001笔记

    java 虚拟机运行时数据区
    方法区-----虚拟机栈-----本地方法栈------堆------程序计数器------执行引擎-------本地库接口-----本地方法库
    ---------几大模块-----------------------------
    jvm类加载机制
    jvm内存区域
    jvm内存模型
    GC之对象生死
    垃圾收集算法
    垃圾收集器
    内存分配策略
    调优工具
      --jconsole
      --jvisualvm
    调优GC参数
    ---类加载-----------------------
    类型的加载,连接与初始化过程都在程序运行期间完成的,提供了更大的灵活性,增加了更多的可能性
    --java虚拟机与程序的生命周期
    在如下几种情况下,java虚拟机将结束生命周期
    1)执行System.exit()方法
    2)程序正常执行结束
    3)程序在执行中遇到异常或者错误而异常终止
    4)由于操作系统出现错误而导致java虚拟机进程终止
    --------5步---------
    加载:查找并加载类的二进制数据
    连接
      --验证:确保被加载的类的正确性
      --准备:为类的静态变量分配内存,并将其初始化为默认值
      --解析:把类中的符号引用转换为直接引用
    初始化:为类的静态变量赋予正确的初始值
    使用
    卸载
    -----
    java程序对类的使用方式可以分为2种
    1--主动使用
    2--被动使用
    所有的java虚拟机实现必须在没个类或接口被java程序"首次主动使用"时
    才初始化它们
    主动使用(7种)
    --创建类的实例
    --访问某个类或接口的静态变量,或者对该静态变量赋值
    --调用类的静态方法
    --反射
    --初始化一个类的子类
    --java虚拟机启动时被标明为启动类的类--类似main,程序入口
    --jdk1.7开始提供动态语言支持
    java.lang.invocke.MethodHandle实例的解析结果
    REF_getStatic,REF_putStatic,REF_invokeStatic句柄对应的类没有初始化
    则初始化
    助记符--getstatic ---putstatic--invokestatic
    被动使用:不会导致类的初始化,但是可能会加载和连接
    -----------类的加载----------
    加载.class文件的方式
    -从本地系统中直接加载
    -通过网络下载.class文件
    -从zip.jar等归档文件中加载.class文件
    -从专有数据库中提取.class文件
    -将java源文件动态编译为.class文件
    ----
    对于静态字段来说,只有直接定义了该字段的类才会被初始化
    当一个类在初始化时,要求其父类全部已经初始化完毕
    -XX:+TraceClassLoading,用于追踪类的加载信息并打印出来
    -XX:+<option>,表示开启option选项
    -XX:- <option>, 表示关闭option选项
    -XX:<option>=<value>,表示将option选项的值设置为value
    ----------------
    final:表示常量,在编译阶段,会存入调用那个方法所在类的常量池中
    本质上,调用类并没有直接引用到定义常量的类。因此并不会触发定义常量类的初始化
    注意:这里指的是将常量存放到了调用方法的类的常量池,可以删除编译后的class文件
    javap -c :反编译
    助记符:

      ldc表示将int,float或是String类型的常量值从常量池中推送至栈顶
      bipush表示将单字节(-128-127)的常量值推送至栈顶
      sipush将一个短整型常量值(-32768-32767)推送至栈顶
      iconst_1表示将int类型1推送至栈顶(iconst_m1-iconst_5)(-1~5)
    ---------类加载器-------
    com.sun.org.apache.bcel.internal.generic;internal表示内部使用
    当一个常量值并非编译期可以确定的,那么其值就不会被放到调用类的常量池中。
    这时候在程序运行时,会导致主动使用这个常量所在的类,显然会导致这个类被初始化
    ---
    对于数组实例来说,其类型是有jvm在运行期间动态生成,表示[
    这种形式,动态生成的类型,其父类类型就是Object
    对于数组来说,JavaDoc经常将构成数组的元素称为component,实际上就是将数组降低一个维度后的类型,
    助记符:
      anewarray:表示创建一个引用类型的(如类,接口,数组)数组,并将其引用值压入栈顶
      newarray:表示创建一个指定的原始类型(如int,float,char等)的数组。并将其引用值压入栈顶。

    接口初始化:

    当一个接口初始化时,并不要求其接口都完成初始化
    只有在真正使用到父接口的时候(例如引用接口中所定义的常量),才会初始化
    --加载:就是把二进制形式的java类型读入java虚拟机中
    --验证
    --准备:为类变量分配内存,设置默认值,但是在到达初始化之前,类变量都没有初始化为 真正的初始值
    --解析:解析过程就是在类型的常量池中寻找类,接口,字段和方法的符号引用,把这些符 号引用替换成直接引用的过程
    --初始化:为类变量赋予正确的初始值
    --类实例化:为新的对象分配内存,为实例变量赋默认值,为实例变量赋正确的初始值
    java编译器为它编译的每一个类都至少生成一个实例初始化方法,在java的class文件中,
    这个实例 初始化方法被称为"<init>".针对源码中的每一个类的构造方法,java编译器都产 生一个<init>方法
    --类的加载的最终产品是位于内存中的Class对象
    --Class对象封装了类在方法区内存的数据结构,并且向java程序猿提供了访问方法区内的数 据结构的接口
    ---类的加载-----
    有两种类型的类加载器
    java虚拟机自带的加载器
    根类加载器(Bootstrap)
    扩展类加载器(Extension)
    系统(应用)类加载器(System)
    用户自定义的类加载器
    java.lang.ClassLoader的子类
    用户可以定制类的加载方式
    --类加载器并不需要等到某个类被"首次主动使用"时再加载它
    --jvm的规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的
    --过程中遇到了.class文件缺失或者存在错误,类加载器必须在程序首次主动使用该类时
    才报告错误(LinkageError错误)
    --如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误
    -------
    1)类被加载后,就进入连接阶段,连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。
    2)类的验证内容
    -类文件的结构检查
    -语义检查
    -字节码验证
    -二进制兼容性的验证
    --类的初始化时机----
    只有当程序访问的静态变量或者静态方法确实在当前或者当前接口中定义时,才可以认为是对类或者接口的主动使用

    类加载器的关系,依次为包含关系

    实例化代码块类中{}
    ========================================
    四种引用类型:
    强引用:只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
    软引用:系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。
    弱引用:被弱引用管联的对象只能生存到下一次垃圾收集发生之前。
    虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。
    --在跟搜索算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正的宣告一个对象的死亡,至少要经历“两次标记过程”:如果对象在进行跟搜索后发现没有与GC Roots 相连接的引用链,那它将会被第一次标记冰洁进行一次筛选,筛选的条件是此对象是否有必要执行finalize().
    **finalize()是Object中的方法,当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,让此对象处理它生前的最后事情(这个对象可以趁这个时机挣脱死亡的命运)
    --1.对象覆写了finalize()方法(这样在被判死后才会调用此方法,才有机会做最后的救赎);
    --2.在finalize()方法中重新引用到"GC Roots"链上(如把当前对象的引用this赋值给某对象的类变量/成员变量,重新建立可达的引用).
    --任何一个对象的finalize()方法都只会被系统自动调用一次,如果对象面临下次回收,它的finalize()方法不会被再次执行,
    --判断无用的类:
    1该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例
    2加载该类的ClassLoader已经被回收。
    3该类对应的java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
    4中垃圾回收算法
    --标记清除:首先标记出所有需要回收的对象,在标记完成后统一回收所有被 标记的对象。
    缺点:标记和清除的效率都不高,空间不连续。
    --复制算法:将可用内存按容量划分大小相等的两块,每次只使用其中的一块,当这一块内用完了,就将还存活的对象复制到另一块上面,然后再把已经使用过的内存空间一次性清理掉。
    :实现简单,运行高效(存活对象较多时,大量复制,效率变低),代价将内存缩小一半。
    这算法回收新生代,Eden和2块Survivor,Eden和Survivor比例8:1.
    --标记整理算法
    :老年代--标记清除--整理
    --分代收集算法:只是根据对象的存活周期的不同将内存划分为几块,这样就可以根据各个年代的特点采用最合适的收集算法。
    垃圾收集器:如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现。
    针对sun hotSpot1.6至Update22

  • 相关阅读:
    Servlet核心技术(上)
    Bootstrap详解
    ECMAScript6详解
    JQuery详解
    CSS详解
    HTML
    网站加载页面(HTML+CSS+JS,简易版)
    java中sort()方法的用法
    Maven常见jar包依赖
    解决idea的项目启动报404的问题
  • 原文地址:https://www.cnblogs.com/liufei-90046109/p/11584537.html
Copyright © 2011-2022 走看看