zoukankan      html  css  js  c++  java
  • JVM 基础知识

    JVM

    1. JVM 的位置

    在操作系统上,可以看成是一个 软件,包含在 JRE 中

    三种JVM

    • Sun 公司 HotSpot(使用最多)
    • BEA JRockit
    • IBM J9 VM

    2. JVM 的体系结构

    不会发生垃圾回收的区域:

    JVM 调优的区域:

    3. 类加载器

    加载器类别

    • 虚拟机自带的加载器
    • 系统类(根)加载器(最终执行)
    • 扩展类加载器
    • 应用程序加载器

    4. 双亲委派机制

    采用这种机制,安全

    AppClassLoder(应用程序加载器) --> PlatformClassLoder(扩展类加载器,JDK 1.9 之后) --> BootstrapClassLoder(系统类加载器)

    执行过程:

    • 类加载器收到类加载的请求
    • 将这个请求向上委托给父类加载器去完成,一直向上委托,直到系统类加载器
    • 系统加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载
    • 重复步骤 3
    • 如出现 null :说明 java 调用不到,因为底层是 c、c++ 写的

    5.沙箱安全机制

    Java 安全模型的核心就是 Java 沙箱(sandbox)

    定义:沙箱是一个限制程序运行的环境,沙箱机制就是将 Java 代码限定在虚拟机特定的运行范围中,并且严格限制代码对贝蒂系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。

    沙箱主要限制系统资源访问,那系统资源包括什么?

    • CPU
    • 内存
    • 文件系统
    • 网络

    目前的安全机制实现,引入了域(Domain)的概念,虚拟机会把所有代码加载到不同的系统域和应用域。

    组成沙箱的基本组件:

    • 字节码校验器(bytecode verifier)
    • 类加载器

    类加载器采用的机制是双亲委派机模式

    6. Native 关键字

    凡是带了 native 关键字的,说明 java 的作用范围达不到了,会去调用底层 c 语言的库!

    会进入本地方法栈,调用本地方法接口:JNI

    JNI 作用:扩展 java 的使用,融合不同的编程语言为 Java 所用!最初:c、c++

    它在内存区域中专门开辟了一块标记区域:Native Method Stack,登记 native 方法,在最终执行的时候,加载本地方法库中的方法通过 JNI

    7. PC 寄存器

    程序计数器(Program Counter Register)

    每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向像一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计

    8. 方法区

    方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数、接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间:

    静态变量(static)、常量(final)、类信息(构造方法、接口定义)、运行时的常量池 都存在方法区中,但是 实例变量存在堆内存中,和方法区无关

    9. 栈

    先进后出

    栈内存,主管程序的运行,生命周期和线程同步

    线程结束,栈内存也就释放啦,对于栈来说,不存在垃圾回收问题

    栈溢出(可能是 递归调用 造成,循环调用,不断压栈)

    存在栈里的内容:

    • 8 大基本类型
    • 对象引用
    • 实例的方法

    栈运行原理:栈帧

    栈满了:StackOverFlowError

    10. 堆

    一个 JVM 只有一个堆内存,堆内存的大小是可以调节的

    类加载器读取了类文件后,把什么东西放到堆中?

    • 方法
    • 常量
    • 变量
    • 所有引用类型的真实对象

    堆内存中细分为三个区域:

    • 新生区
    • 老年区
    • 元空间(永久区)

    GC 垃圾回收,主要发生在 新生区 和 老年区

    当一个对象经历了 15 次 GC 后,就会进入 老年区

    假设内存满了,会发生 OOM(堆内存不够)

    11. 新生区、老年区、元空间(JDK8之前为永久区)

    永久区用来存放 JDK 自身携带的 Class 对象、Interface 元数据、存储的是 java 运行时的一些环境或类信息,这个区域不存在垃圾回收,关闭虚拟机会释放这个区域的内存

    若一个启动类,加载了大量的第三方 jar 包,Tomcat 部署了太多的应用,大量动态生成的反射类,不断的被加载,直到内存满,就会出现 OOM

    元空间 逻辑上存在,物理上不存在

    12. 堆内存调优

    分析出现 OOM 的原因:

    • 尝试扩大堆内存空间看结果(默认情况下:分配的总内存是电脑内存的 1/4,而初始化的内存为:1/64)

    • 使用工具进行分析第几行代码出错

      内存快照分析工具,Jprofiler

      作用:可以分析 Dump 内存文件,快速定位内存泄漏,获得堆中的数据,获得大的对象

    13. GC 常用算法

    • 引用计数法

    • 复制算法

      在幸存区中,from 和 to 会不停交换,谁空谁是 to,为了保证其中一个是空的,使用复制算法将其中一个复制到 to 中,再将另一个作为 to,保证 to 是空的

      好处:没有内存的碎片

      坏处:浪费了内存空间

    • 标记清除算法

      扫描对象,对活着的对象进行标记

      清楚没有标记的对象,进行删除

      优点:不会浪费内存空间

      缺点: 两次扫描,消耗了更多的时间。且又内存碎片产生

    • 标记压缩算法

      防止内存碎片产生,再次扫描,向一端移动存活的对象,但多了一个移动成本

    14. GC 算法总结

    内存效率:复制效率 > 标记清楚算法 > 标记压缩算法 (时间复杂度)

    内存整齐度:复制算法 = 标价压缩算法 > 标记清除算法

    内存利用率:标记压缩算法 = 标记清除算法 > 复制算法

    没有最好的算法,只有最合适的算法

    GC 为分代收集算法

    ​ 年轻代:

    ​ 存活率低:复制算法

    ​ 老年代:

    ​ 区域大,存活率高

    ​ 标记清除(内存碎片不是太多)+ 标记压缩混合 实现

    Now is better than never
  • 相关阅读:
    DataGird导出EXCEL的几个方法
    csv文件与DataTable互相导入处理
    LeetCode 345
    LeetCode 168
    LeetCode 344
    LeetCode 342
    LeetCode 343
    LeetCode 326
    LeetCode 338
    LeetCode 319
  • 原文地址:https://www.cnblogs.com/alivinfer/p/14512353.html
Copyright © 2011-2022 走看看