zoukankan      html  css  js  c++  java
  • 初识JVM

    JVM探究

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

    1、JVM的体系结构

    2、类加载器和双亲委派机制

    要了解双亲委派机制得先了解个概念:

    类加载器:“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块成为“类加载器”。

    通俗的讲,虚拟机是根据类的全限定名来加载类的,那么有个问题,如果同时存在两个或多个全限定名完全一致的情况下。该如何选择加载哪个类。这就是双亲委派机制要做的工作。

    双亲委派机制得工作过程:

    1-类加载器收到类加载的请求;

    2-把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器;

    3-启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载。

    4-重复步骤三;

    详细见:双亲委派机制

    3、沙箱安全机制

    什么是沙箱?
     Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。

    4、Native、pc寄存器、方法区

    Native

    native:凡是带了native关键字的,说明Java的作用范围达不到了,需要调用本地接口方法(其他语言的库)。

    1、带了native关键字的,首先会进入运行时数据区中的本地方法栈中,然后调用相应的本地方法接口JNI(Java Native Interface),从本地方法库中找出相应的方法。

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

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

    PC寄存器

    程序计数器 program Counter Register

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

    方法区 Method Area

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

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

    5、栈

    先进后出

    栈内存:主管程序的运行,生命周期和线程同步。线程结束,栈内存也就释放。所以说,不存在垃圾回收的问题。

    栈内存存储:8大基本类型、对象引用、实例的方法引用

    深入理解请看

    6、堆

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

    当Java程序创建一个类的实例或者数组时,都在堆中为新的对象分配内存。bai虚拟机中只有一个堆,所有的线程都共享他。Java中所有的对象都存放在堆中,包括class对象和异常对象。

    其实,堆内存细分为三个区域:

    • 新生区(伊甸园区eden、幸存0区survivor0、幸存1区survivor1)

      类诞生、成长、甚至死亡的地方

      • 伊甸园区,所有的对象都是在伊甸园区new 出来的
      • 幸存区(0,1)
    • 养老区 old

    ​ 经过gc垃圾回收幸存留下来的对象存放在这。

    ​ 其实,99%的对象都是临时对象!

    • 永久区(元空间) permanent

      这个区域是存放的常驻内存的。用来存放JDK自身携带的class对象。interface元数据,存储的是Java运行时的一些环境或类信息,这个区域不存在垃圾回收!关闭KVM虚拟就会释放这个区域的内存~

    在JDK7以及其前期的JDK版本号中。堆内存通常被分为三块区域Nursery内存(young generation)、长时内存(old generation)、永久内存(Permanent Generation for VM Matedata),显演示样例如以下图:

    img

    7、GC垃圾回收

    JVM在进行GC时,并不是对这三个区域统一回收。大部分时候,都是在新生区

    • 新生区
    • 幸存区
    • 老年区

    GC分为两类:轻GC(Miner GC,回收新生区和幸存区中的垃圾)重GC(Full GC,全局回收垃圾,包括老年区)

    GC的算法:标记清除法、标记压缩法、复制算法、引用计数法。

    引用计数法:

    设置一个计数器,记录对象的调用次数,对此来进行垃圾回收。

    复制算法:

    每次GC后,将新生区和幸存from区中活下来的对象复制存放到幸存to区,同时清空新生区和幸存from区,

    此时from区清空后变为to区,to区被复制过去对象后变为了from区。

    谁空谁是to区

    经历过15次GC后,仍然留下来的对象会转移到老年区中。

    标记清除压缩法:

    标记清除

    1、先将活着的对象进行标记,

    2、然后把没有标记的对象删除掉

    标记压缩(标记整理)

    1、先将活着的对象进行标记

    2、然后将标记的对象向前移动压缩。

    总结:

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

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

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

  • 相关阅读:
    关于PHPExcel直接读取Excel文件两种方法
    关于CSS
    PHP数组——自定义排序
    MYSQL常用函数
    uniapp 子组件给子组件传值
    uniapp 子组件给父组件传值
    uniapp 父亲给子组件传值
    uniapp 百度小程序 navigator跳转页面&传参
    uniapp 百度小程序预览图片
    js filter过滤,map映射 filter和map的用法
  • 原文地址:https://www.cnblogs.com/xiaopanjava/p/14019049.html
Copyright © 2011-2022 走看看