zoukankan      html  css  js  c++  java
  • 真正读懂jvm

    一、java 文件在jvm 中的执行过程

    一、装载
    1.将java文件编译成字节码文件,字节码文件是java 虚拟机可以识别的文件
    2.将java 字节码文件通过流的方式装载到内存,也就是按照虚拟机所需的格式存储在方法区中,同时在java 堆中生成一份java.lang.Class 对象,这个对象是作为类的访问入口
    二、验证
    1.验证二进制字节流中的信息符合jvm 存储规范,是否按照0xCAFEBABE开头,主次版本号是否在当前虚拟机的所在范围
    2.元数据验证,保证其描述的信息符合java 语言规范
    三、准备
    1.正式为类的静态变量分配内存和分配初值,这个内存分配是在方法区中分配的
    2.在准备阶段会给常量赋默认值,比如0,false,null 等,但是如果是final 常量,则准备阶段直接赋于最终的值(代码中指定的值)
    四、解析
    1.将符号引用转为直接引用,也就是将虚拟机常量池中的符号引用(int a=)转为直接引用(变量的内存地址),符号引用只是用文本的方式表示引用关系,而符号引用是jvm可以直接使用的形式,主要表现为直接指针
    五、初始化
    1.给申明的类变量指定初始值,如a=3
    2.给类的静态代码块变量指定初始值
    3.如果该类的父类没有初始化,则先初始化该类的父类
    4.类的初始化时机包括:new ;访问某个类的静态变量或赋值;反射(Class.forName);被标明为启动类的类
    六、生命周期结束
    1.生命周期结束的集中情况:执行System.exit();程序正常执行结束;程序遇到异常或错误导致执行结束;操作系统错误导致结束

     二、jvm 内存模型(运行时数据区)

     

    1.方法区:用户存储虚拟机加载的类信息、常量、静态变量,是各个线程共享的区域。

    2.堆:用来存储对象及数组实例,是jvm 管理内存的最大一块区域,分为老年代和年轻代,堆也是各个线程共享的区域。

    3.java 虚拟机栈:java 方法执行的内存区域,用来存储局部变量表,操作数栈、方法出口,虚拟机栈是线程私有的,每个线程调用方法都会产生一个栈

    4.本地方法栈:和虚拟机栈类似,虚拟机栈是为虚拟机执行的java方法服务,而本地方法栈是为虚拟机执行的native 方法(c++写的)服务;

    5.程序技术器:用来记录当前线程执行的字节码的行号指令器,分支、循环、异常处理、线程恢复都要依赖于程序计数器,通过程序计数器来选取下一条程序执行的字节码指令,程序计数器也是线程私有的。

    三、java 虚拟机栈执行过程

     1.当某个线程在执行时,先开辟一块栈空间,在栈空间中每调用一次方法就会生成一个栈帧,每个栈帧,也就是方法遵循先进后出

    2.栈帧中包含:局部变量表、操作数栈、动态连接、方法出口

    3.一段代码解释java 虚拟机栈的全过程

     (1)主线程开始执行,开辟一份栈空间

    (2)main 方法开始执行,生成main 方法的栈帧

    (3)new 对象,在堆空间生成一个对象,并在栈帧地局部变量表中生成一份指针

    (4)开始执行add 方法,生成add 方法的栈帧

    (5)栈帧中包含的信息有:局部变量表,操作数栈(一个临时存储空间,用来计算)、动态连接、方法出口

    (6)add 方法执行结束后,会出栈,然后mai'n 方法接着执行,而具体执行的行出是根据程序计数器来记录具体的行数

     四、方法区 jdk 1.7 和1.8 的区别

    1.在j'd'k 1.7  中方法区叫做永久代,而1.8中叫元数据,元数据和永久代的区别是,元数据使用了物理机的直接内存,直接内存的好处是不容易发生内存溢出,缺点是会产生内存碎片,而永久带的缺点是不好规划内存空间大小。

    2.方法区中存放的数据是类的class 信息,包括:类的加载器引用;常量池、字段,每个字段的类型、修饰符、名字等;方法数据和方法代码

    五、栈帧的动态链接

    1.动态链接:方法对象的地址,动态链接是找到正确方法的入口,也就找到了对应的字节码指令,然后才有后来进栈出栈的执行

    2.动态链接指在类的装载过程中不能通过符号引用专为直接引用,而在运行时才知道的,比如接口回调、多态、重载等

    六、jvm 堆的内存分布

    1.堆内存分为新生代和老年代,新生代分为Eden 区、from 区、to 区,内存回收时通过不断的切换from 和to 来回倒腾

     七、对象在jvm中的内存分布

    1.jvm 中的内存分布主要包括四大部分:mark word (8字节),类型指针(压缩后4字节),实例数据,对齐填充

    2.通过以下方式查看对象的内存分布

    import com.sl.spring.framework.beans.SLBeanDefinition;
    import org.openjdk.jol.info.ClassLayout;
    
    
    public class test {
        public static void main(String[] args) {
            SLBeanDefinition beanDefinition=new SLBeanDefinition();
            System.out.println(ClassLayout.parseInstance(beanDefinition).toPrintable());
        }
    }

     2.mark word 内存分布:hash 值、GC 分代年龄、锁等信息

    八、jvm 垃圾回收算法

    1.标记清除算法:通过可达性算法,标记哪些可达的对象,然后清除未标记的对象

    2.标记清除算法(复制法):先将可达的对象复制到另一块区域,然后再清除

    3.标记清除整理算法:

    4.几种不同的垃圾回收期算法

     5。垃圾回收过程中存在的问题:

    1)垃圾回收线程和用户线程同时运行会存在两个问题,1,该回收的没有回收;2,不该回收的回收了,3,如果 stop world 则会出现停顿

    2)针对上面的问题,有两个解决办法 1,垃圾回收线程执行时,停止整个世界(其他业务线程停止)2,两种线程一部分过程并行,一部分同步,如,标记的时候只标记gc root ,然后再做一次标记,最后一起结束(这里有点绕),需要一个图;3,多次垃圾回收,每次回收一点一点,这样导致吞吐量降低(G1 垃圾收集器)

     九、jvm 调优及调优工具

  • 相关阅读:
    记录-tomcat启动项目配置
    记录 -- js浏览器窗口关闭调用ajax
    远程桌面时出现身份验证错误,要求的函数不受支持
    记录-马斯洛需求层次理论模型
    记录-powerDesigner 导入sql文件注释问题
    记录-Java md5加密
    记录--js 剪贴板操作 (转载)
    如何判定一台计算机的唯一性
    GO_OOP简单摘要
    后台执行命令
  • 原文地址:https://www.cnblogs.com/lufei33180/p/14329939.html
Copyright © 2011-2022 走看看