jvm

一.运行时数据区

  1.线程共享和线程私有:

    01.线程共享:

       堆,方法区

    02.线程私有:

       虚拟机栈,本地方法栈,程序计数器

  2.程序计数器

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

    能够在线程切换之后,找到自己正确的位置

    是唯一一个不会导致内存泄漏(OutOfMemory,OOM)的区域

  3.虚拟机栈:

    基本数据类型的变量和对象的引用变量都存在此区域;

    遵循“先进后出,后进先出”

  StackOverFlowError:

    线程请求的栈深度大于了虚拟机规定的最大深度

  OutOfMemoryError:

    虚拟机在扩展栈时,无法申请到足够的内存空间!

  4.本地方法栈

    主要服务于Native修饰的方法

    在HotSport中虚拟机栈和本地方法栈合为一体

 堆:

  所有对象的实例和数组开辟空间都在此区域保存!

  所有线程共享

  GC主要回收对象的区域

 1.堆分区:新生代,老年代,永久代

 2.方法区(静态去)

   所有线程共享;

   方法(包含构造函数),接口 定义在此区域;

   所有方法的信息

   静态变量+常量+类信息+方法信息+常量池 

 

二.类的生命周期:

  类的生命周期从类被加载,连接和初始化开始到类的卸载结束

   01.类的生命周期中,类的二进制位于方法区;

   02.在堆中会有一个描述这个类的Class对象;

  2.1加载将class字节码文件内容加载到内存中,并将这些静态数据转换成方法区中运行时数据结构,在堆中生成一格Class对象;这个Class对象就是方法区类数据的访问入口

  2.2链接

   0.1类的验证

    001.类文件的结构检查

    002.语义检查 比如说final修饰的变量在编译期间发现再次赋值

    003.字节码验证,确保字节码能被jvm识别

   0.2类的准备

    为类中所有static修饰的内容开辟空间,并赋予初始值!!

    static  int  num=100;

    这时候 num=0;

   0.3类的解析

    符号引用:就是用字符串的形式来表示某个变量或是类,我们能看懂String a="a"; Student stu=new Student();

    直接引用:是根据符号引用翻译出来的地址!

   2.3 初始化

    加载不是初始化

    初始化指的是实例化!创建出类的实例!

    初始化的时机

     01.类的主动引用

      001.new一个类的对象

      002.通过反射的newInstance();

      003.再初始化子类时候必须先初始化父类

     02.类的被动引用

      001.通过类名访问静态内容

      002.调用类的静态常量也会不会初始化类

      003.用类作为对象数组存在时,也不会初始化类

      004.子类调用父类的静态变量不会加载子类的静态代码块(不会执行类的准备阶段)

JVM垃圾回首机制

一.垃圾回收机制(GC)
  1.1:为啥需要垃圾回收机制
  01.只要是对象被创建,那么就会在虚拟机的堆中开辟空间;
  02.程序运行过程中会创建N个对象,美哥对象都会有自己的空间;
  03.如果每个对象都永久的占领这块空间,显然内存是不够的

    总结:为了保证其他对象能够被正确的创建!!
  在C语言中,垃圾回收的任务是程序员自身负责的
  可能会出现的问题:
  01.由于程序猿粗心大意,导致煤油及时释放不使用的对象,释放错误!
  02.程序猿一旦释放了程序核心对象(比如说系统对象),系统崩溃!

  1.2:垃圾回收机制的定义
  在java程序运行过程中,jvm有一个专门负责回收那些不再使用的对象
  所占的内存,这种回收的过程,我们称之为垃圾回收机制(GC,Garbage Collection)
  1.3:垃圾回收机制的特点
  01.减轻了程序猿进行内存管理的负担
  02.防止系统内存被非法释放,使我们的程序更加健壮
  03.只有在对象不被任何变量引用时,才能被回收
  04.程序无法让垃圾回收机制强行回收垃圾操作
  05.当垃圾回收机制将要回收不用的对象内存时,会先调用这个对象的finalize()
    这个方法可能使对象复活,导致垃圾回收器取消对该对象的回收。:
  1.4:对象的状态
    在虚拟机的垃圾回收器来看,堆中所有的对象都有三种状态!
  01.可触及状态
  02.可复活状态
  03.不可触及状态
  直邮对向出于不可触及状态的时候,垃圾回收机制真正的释放对象所占有的内存

       1.对象的生命周期开始(new语句或者是反射值的newInstance)
  2.对象不再被引用,或者对象调用了finalize()
  3.对象调用了finalize()
  4.垃圾回收
  5.对象生命周期结束 垃圾何时被回收    
    01.对象没有引用    
    02.程序在作用域正常执行完毕后    
    03.System.sxit();    
    04.程序意外终止  
  讲解GC
  01.什么时间======触发GC条件      
    001.System.gc();      
    002.系统自身决定GC的触发时机      
    003.根据eden区和feom space区打大小决定
  02.对什么东西   
  Java中的对象====通过分析算法无法找到的对象
  03.做了什么   
    对搜到的对象进行复制操作   对搜索不到的对象执行finaize  如果真正的回收一个对象,至少需要两次标记! 
01.第一次标记:对于一个没有其他对象引用的时候执行finalize()  
02.第二次标记:对于筛选过的对象,进行回收java的内存分配机制  
  核心:分代分配,分代回收 新生代  
    Eden区         :是连续的内存空间,所以分配的极快  
    survior区       :From To必须有一个区域是空的  
    老年代 :永久带  
    注意事项:
  01.绝大多数创建的对象分配到Eden区是,但是大多数对象会在这个区域死亡
  02.当Eden区满的时候,会执行Minor GC,将死亡的对象清除掉剩余存活的对象会放到survior0区
  03.以后每次Eden满的时候会执行Minor GC,所有存活的对象又被放进survivor0区
  04.当survivor0满的时候会把存活的对象复制到survivor区,之后清空survivor0去
  05.反复执行之后,任然活着的对象复制到老年代
  06.老年代的对象要比年轻代的大,当然也有满的时候,这是就会执行Maior GC(Full GC)
  07.如果对象比较大,年轻代放不下直接放入老年代! 
    Yong  GC和FullGC的区别   
  01.Y GC是在新生代的Eden区满,survivor区满的时候触发的       Full GC是在老年代满的时候触发的   
  02.YongGC执行效率高      
    Full GC执行速率低 什么时候触发Full GC   
  01.执行System.gc(),系统建议执行Full GC单不是必须执行   
  02.老年代空间不足      
  001.当Yong  GC执行后存活的对象需要进驻到老年代,但是发现老年代空间不足      
  002.当Survivor0去Survivor1区来回切换时,发现内存不足,必须放进老年代。  
    03.方法区空间不足    
  GC涉及到的算法 
  引用计数法   给对象添加一个引用器,使用一次加一,少一个引用减一!  当引用为0是进行回收  但是不能解决循环引用的问题根据搜索法对象根为起点,向下延伸,延伸的路径我           们称之为引用链(  )当一个对象没有任何引用链时,证明这个对象是不可用对象(不可达到) 会被回收 什么是根   
  01.在方法区中常量引用的对象   
  02.栈中引用的对象   
  03.静态属性引用的对象  复制算法图解 解释   就是讲原有的空间,每次都是使用其中一块   缺点就是浪费一半的空间!   不适合在对象存活多的情况下使用   在新生代使用标记清除算法 图解  解释     
    001.吧所有存活的对象打个标记    
    002.把所有没有标记的对象统一清除缺点  
  01.两个过程效率都很慢,因为需要查询  
  02.因为在清除的过程中会产生内存碎片,如哥有打对象无法存储  标记整理算法图解 解释适合存活多的区域,所以适合在老年代使用!                   
原文地址:https://www.cnblogs.com/wang2386033566/p/9359280.html