• JVM内存区域


    1. 程序计数器(线程私有)

    当前线程所执行的字节码的行号指示器,占用空间小。

    线程执行Java方法:计数器记录正在执行的虚拟机字节码指令的地址;

    线程执行Native方法:计数器为空。

    此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

    2 虚拟机栈(线程私有)

    每个方法在执行的同时会创建一个栈帧用于存储对于局部变量表、操作数栈、动态链接、方法出口等信息,然后放入栈中。每个时刻正在执行的当前方法就是虚拟机栈顶的栈帧。方法的执行就是对应着栈帧在虚拟机栈中入栈和出栈的过程。

    本区域的两种异常情况:

    StackOverflowError异常:线程请求的栈深度大于虚拟机所允许的深度;

    OutOfMemoryError异常:虚拟机栈动态扩展到无法申请到足够的内存。

    3 本地方法栈(线程私有)

    与虚拟机栈发挥的作用相似,JVM简单的动态链接并直接调用nativa方法;

    二者区别是:虚拟机栈为虚拟机执行Java方法(字节码0)服务;

    本地方法栈为虚拟机使用到的Native方法服务。

    本区域的两种异常情况:

    StackOverflowError异常:线程请求的栈深度大于虚拟机所允许的深度;

    OutOfMemoryError异常:本地方法栈动态扩展到无法申请到足够的内存。

    4 堆(线程共享)

    Java虚拟机锁管理内存中最大的一块,所有线程共享的一块区域;

    垃圾收集器管理的主要区域,也被称作GC堆;

    可用以下参数调整:

    -Xms: 堆的最小值;

    -Xmx: 堆的最大值;

    -Xmn: 新生代的大小;

    -XX:NewSize: 新生代最小值;

    -XX:MaxNewSize: 新生代最大值;

    本区域的异常情况:

    OutOfMemoryError异常:堆无法申请到足够的内存。

    方法区/永久代(线程共享),别名Non-Heap

    用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    运行时常量池属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

    本区域的异常情况:

    ① OutOfMemoryError异常:方法区无法满足内存分配需求。

    可用以下参数调整:
    jdk1.7及以前:-XX:PermSize-XX:MaxPermSize
    jdk1.8以后:-XX:MetaspaceSize-XX:MaxMetaspaceSize
    jdk1.8以后大小就只受本机总内存的限制
    如:-XX:MaxMetaspaceSize=3M

    6 直接内存(线程共享)

    不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。如果使用了NIO(New Input/Output),本区域会被频繁的使用。在Java堆中可以用DirectByteBuffer对象作为这块内存的引用进行操作。

    这块内存不受java堆大小限制,但受本机总内存的限制,可以通过-XX:MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常。

    各个版本内存区域的变化

     

     

    线程的角度看内存

    深入辨析堆和栈

     

    未完待续...

  • 相关阅读:
    005 ES的文档一些控制
    004 REST风格中在ES中的约定
    003 接触elasticsearch的Restful Api【快速入门】
    002 elasticsearch中的一些概念
    001 centos7下安装kibana
    000 centos7下安装elasticsearch7的单节点安装
    006 DOM节点操作与元素的创建
    006 认识BeanNameAware
    005 Spring和SpringBoot中的@Component 和@ComponentScan注解
    004 JpaRepository,CrudRepository,PagingAndSortingRepository的区别
  • 原文地址:https://www.cnblogs.com/xuzhuteng/p/14983681.html
Copyright © 2020-2023  润新知