zoukankan      html  css  js  c++  java
  • 目录 1.1. JVM内存模型总体架构图 1 1.2. JAVA堆 2 1.3. 方法区 元空间(Metaspace) 2 1.4. 虚拟机栈 3 1.5. 本地方法区 4 2. 垃圾回收算法 4 2

    目录

    1.1. JVM内存模型总体架构图 1

    1.2. JAVA堆 2

    1.3. 方法区 元空间(Metaspace) 2

    1.4. 虚拟机栈 3

    1.5. 本地方法区 4

    2. 垃圾回收算法 4

    2.1. 标记-清除算法(Mark-Sweep) 4

    2.2. 复制算法(copying) 4

    2.3. 标记-压缩算法(Mark-compact) 5

    3. JVM参数: 6

    4. 查看工具 7

    4.1. jconsole.exe 7

    4.2. D:\jdk1.8.0_31\bin\jvisualvm.exe 8

    5. ref 8

      1. JVM内存模型总体架构图

      1. JAVA堆


    线程共享的,存放所有对象实例和数组。垃圾回收的主要区域。可以分为新生代和老年代(tenured)。
    新生代用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够长,老年对象就会被移入老年代。
    新生代又可进一步细分为eden、survivorSpace0(s0,from space)、survivorSpace1(s1,to space)。刚创建的对象都放入eden,s0和s1都至少经过一次GC并幸存。如果幸存对象经过一定时间仍存在,则进入老年代(tenured)。

      1. 方法区 元空间(Metaspace)


    线程共享的,用于存放被虚拟机加载的类的元数据信息:如常量、静态变量、即时编译器编译后的代码。也成为永久代。如果hotspot虚拟机确定一个类的定义信息不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装载该类的ClassLoader被回收

    元空间(Metaspace)

    3.1元空间的内存大小

    元空间是方法区的在HotSpot jvm 中的实现,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫“非堆”。

    元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。,理论上取决于32位/64位系统可虚拟的内存大小。可见也不是无限制的,需要配置参数。

    根据上面的各种原因,永久代最终被移除,方法区移至Metaspace,字符串常量移至Java Heap

    随着JDK8的到来,JVM不再有PermGen。但类的元数据信息(metadata)还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory)中。

    程序计数器
    多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。

      1. 虚拟机栈


    线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个桢栈来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。
    使用jclasslib工具可以查看class类文件的结构。下图为栈帧结构图:

      1. 本地方法区


    和虚拟机栈功能相似,但管理的不是JAVA方法,是本地方法,本地方法是用C实现的。

    1. 垃圾回收算法
      1. 标记-清除算法(Mark-Sweep)

    从根节点开始标记所有可达对象,其余没标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。
     

      1. 复制算法(copying)


    将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另外一块中,然后完全清除原来使用的那块内存。复制后的空间是连续的。复制算法适用于新生代,因为垃圾对象多于存活对象,复制算法更高效。在新生代串行垃圾回收算法中,将eden中标记存活的对象拷贝未使用的s1中,s0中的年轻对象也进入s1,如果s1空间已满,则进入老年代;这样交替使用s0和s1。这种改进的复制算法,既保证了空间的连续性,有避免了大量的内存空间浪费。

      1. 标记-压缩算法(Mark-compact)


    适合用于老年代的算法(存活对象多于垃圾对象)。
    标记后不复制,而是将存活对象压缩到内存的一端,然后清理边界外的所有对象。


     

    1. JVM参数:

    -XX:+PrintGCDetails  打印垃圾回收信息

    -Xms 为Heap区域的初始值,线上环境需要与-Xmx设置为一致,否则capacity的值会来回飘动
    -Xmx 为Heap区域的最大值
    -Xss(或-ss) 线程栈大小(指一个线程的native空间)1.5以后是1M的默认大小
    -XX:PermSize与-XX:MaxPermSize  方法区(永久代)的初始大小和最大值(但不是本地方法区)
    -XX:NewRatio  老年代与新生代比率
    -XX:SurvivorRatio  Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。
    -XX:MaxHeapFreeRatio  GC后,如果发现空闲堆内存占到整个预估的比例小于这个值,则减小堆空间。
    -XX:MinHeapFreeRatio  GC后,如果发现空闲堆内存占到整个预估的比例大于这个值,则增大堆空间。
    -XX:NewSize    新生代大小

    1. 查看工具
      1. jconsole.exe

      1. D:\jdk1.8.0_31\bin\jvisualvm.exe
    1. ref

    JDK8-废弃永久代(PermGen)迎来元空间(Metaspace) - 只会一点java - 博客园.html

  • 相关阅读:
    (CSDN迁移)js中的判空
    (CSDN迁移) 输入一个链表,从尾到头打印链表每个节点的值
    (CSDN迁移) 替换字符串中的空格
    (CSDN迁移) Java路径获取
    Apache JMeter 做接口并发测试
    用Postman做接口测试
    高并发或高负载下的系统设计
    编译时异常与运行时异常的区别
    使用JUNIT进行单元测试
    hexo 博客如何更换电脑
  • 原文地址:https://www.cnblogs.com/attilax/p/15197430.html
Copyright © 2011-2022 走看看