zoukankan      html  css  js  c++  java
  • JVM基础探究

    JVM探究

    • 请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?
    • 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
    • JVM的常用调优参数有哪些?
    • 内存 快照如何抓取,怎么分析Dump文件?
    • 谈谈JVM中,你对类加载器的认识?
    1. JVM的位置

    2. JVM的体系结构

    3. 类加载器

      1. 虚拟机自带的加载器

      2. 启动类加载器(根加载器)rt.jar包

      3. 扩展类加载器 /lib/ext,父类加载器为null。null的原因是java访问不到,因为java的基层是用C、C++写的。

      4. 应用程序加载器 ,父加载器为扩展类加载器

    4. 双亲委派机制

    即用一个类时,会向上委托,一直到根加载器,若找到就用根加载器中的类,找不到就抛出异常,在子类即扩展类加载器中找,找到就用,找不到就再向下,层层递进,直到找到,若最后都没找到就抛出一个ClassNotFound。

    1. 沙箱安全机制

    2. Native

      1. 凡是带了native关键字的,表名java作用范围达不到了,需要调用底层C语言库。会进入本地方法栈,调用本地方法接口(JNI)

      2. JNI的作用是扩展java的使用,融合不同的语言为java使用。最初是融合C和C++。

      3. java诞生的时候C和C++横行,想要立足,必须调用C和C++程序,因此,在内存中专门开辟了一块标记区域:Native Method Area,登记native方法,最终在执行的时候通过JNI加载本地方法库中的方法

    3. PC寄存器

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

    4. 方法区(Method Area)

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

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

      static、final、Class、常量池

    5. 栈:先进后出(桶)

      队列:先进先出(FIFO)

      栈内存,主要负责程序的运行,生命周期和线程同步,线程结束,栈也就释放内存,对于栈来说不存在垃圾回收。

      栈:8大基本类型+对象引用+实例的方法

      栈满了:StackOverflowError

    6. 三种JVM

      • sun公司的Hotspot

      • BEA: JRockit

      • IBM: J9 Vm

    7. 堆(Heap)

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

      类加载器读取了类文件后,一般会把什么东西放到堆中?类、方法、常量、变量~,保存引用类型的真是对象;

      • 新生区(伊甸园区)Young/New

      • 养老区 Old

      • 永久区

        • 说明:一般垃圾回收回收新生区的伊甸园区,而经历了垃圾回收没有被回收的就会进入幸存区(幸存0区和幸存1区也是不断交换的而不是固定的)。而在幸存区定了一个次数(例30次),若在经历30次的垃圾回收后,就会进入老年区。一般GC垃圾回收发生在伊甸园区和老年区。

        • 堆内存满了:OOM

        • JDK8以后,永久区改名为元空间

    8. 新生区、老年区

      新生区:

      • 类:诞生和成长的地方,甚至死亡
      • 伊甸园:所有的对象都是在伊甸园区new出来的
      • 幸存者去(0,1)

      ​ 过程:假设伊甸园区有10个空间,当伊甸园区满了之后,就会触发一次轻GC,将没有引用的对象回收,而还有引用的对象就会进入幸存者区,当幸存者区也满了之后,就会触发一次重GC,将伊甸园区和幸存者区都清一遍,幸存下来的进入老年区,当老年区经历多次重GC后也满了,就会出现OOM。

      经研究:99%对象都是临时对象

    9. 永久区

      这个区域常驻内存的,用来存放Java自带的Class对象,Interface元数据。存储的都是Java运行时的一些环境或类信息,一般不存在垃圾回收,在关闭JVM的时候就会释放这个区域的内存。

      永久区什么时候会崩掉呢?

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

    10. 堆内存调优

      -Xms:设置初始化内存大小,默认1/4

      -Xmx:设置最大分配内存,默认1/64

      -Xms1024m -Xmx1024m -XX:+PrintGCDetailse:打印GC垃圾回收信息

      -Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError:OOM的Dump

    11. GC

      GC垃圾回收并不是对这三个统一回收,GC垃圾回收发生在新生代与老年代,其中大部分在新生代。

      • 新生代
      • 幸存区(from,to)
      • 老年区

      GC两种回收:轻GC(普通的GC),重GC(全局的GC)

      GC题目:

      • JVM的内存模型和分区,详细到每个区放什么?

      • 堆里面的分区有哪些?Eden,from,to,老年区,说说他们的特点。

      • GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数器,怎么用的?

        引用计数法:

        计数器进行计数,对象C被引用0次,所以会被清除出去。

        复制算法:

        复制算法就是将幸存区中一个里面的数据复制到另一个里面,这时,空的那个就变成to区。这个算法是为了保证to区永远干净。

        • 好处:没有内存碎片
        • 缺点:浪费了内存空间。永远有一半空间是空的(to区)

        复制算法的最佳使用场景:对象存活度较低的时候。

      • 标记清除算法

        对内存中的对象进行扫描,对存活的对象进行标记,然后将没有标记的对象进行清除。

        优点:不需要额外的空间

        缺点:两次扫描,浪费时间,且会产生内存碎片。

      • 标记压缩(也称标记清除压缩)

        在标记清除的基础上,再次扫描,向一端移动存活对象。但多了一个移动成本。

      • 轻GC和重GC分别在什么时候发生?

      总结:

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

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

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

      年轻代:

      • 存活率低
      • 复制算法

      老年代:

      • 标记清除
    12. JMM(Java Memory Model:Java内存模型)

      1. 什么是JMM

      2. 它干嘛的?(官方、其他人的博客、对应的视频)

        作用:缓存一致性协议,用于定义数据读写规则。(遵守,找到这个规则)

      3. 它该如何学习?

  • 相关阅读:
    k8s资源需求和限制, 以及pod驱逐策略
    python转义引起的错误
    nginx location 匹配目录
    kubelet 证书自动续期
    docker常见退出码
    (转)firefox火狐浏览器语言设置
    去掉表的identity属性
    SQL Server内存方面知识收集
    SQL Server 中not in和not exists
    Data Compression(1)
  • 原文地址:https://www.cnblogs.com/Lv-orange/p/13283106.html
Copyright © 2011-2022 走看看