• Java内存模型


    java的内存区域划分

      根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:

        程序计数器(Program Counter Register)

        Java栈(VM Stack)

        本地方法栈(Native Method Stack)

        方法区(Method Area)

        堆(Heap)

      如下图: 
      

     

      看到这个模型,使用堆和栈划分内存区域还是很有道理的,java虚拟机规范将方法区描述为堆的一个逻辑部分

      这种模型和我们粗略的内存模型的对应关系为:

        堆=堆+方法区  

        栈=虚拟机栈+本地方法栈


    • 程序计数器

      线程隔离,即每个线程都有自己的程序计数器,并且互不影响。分为两种情况,当线程正在执行的是一个java方法,它的作用是作为字节码的行号指示器,指向下一条需要执行的指令。当线程正在执行的是一个Native方法,那么它的值为空(Undefined)。java虚拟机规范中唯一没有定义OOM(OutOfMemoryError)异常的内存区域。

    • java虚拟机栈

      线程隔离,生命周期与线程相同。它描述的是java方法执行的内存模型,每一个java方法执行的时候都会产生一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。当进入一个方法时,栈帧的大小是编译器确定的,运行时不会改变其大小。当虚拟机栈不可扩展的时候,可能抛出StackOverflowError异常,反之,可能抛出OOM异常

    • 本地方法栈

      与java虚拟机栈功能一致,只不过本地方法栈是针对Native方法的。同样在虚拟机规范中定义了StackOverflowErrorOOM两种异常。

    • Java堆

      Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
      Java虚拟机规范中的描述为:所有的对象实例以及数组都要在堆上分配。
      只要是用到new关键字创建的对象都会进入到这个区域,包括对象,数组
      堆还能进一步划分,比如按照内存回收的角度来看,堆可以进一步划分为新生代(Eden+Survivor)老年代。按照内存分配的角度来看,堆可以进一步划分为多个线程私有的分配缓存区,即TLAB(Thread Local Allocation Buffer)。这种进一步的划分是为了更高效地回收和分配内存。java虚拟机规范中定义了OOM异常

    • 方法区

      这个区域很容易引发误会,很多人会以为方法区会存储方法中的局部变量,然而并不是。方法区与Java堆一样,是各个线程共享的内存区域,这个区域用于存储被加载的类的信息,常量,静态变量以及即时编译器编译后的代码等数据。Java虚拟机把方法区描述为堆得一个逻辑部分。虚拟机规范中定义了OOM异常。还需要注意的一点是,HotSpot虚拟机中的方法区被很多人称之为“永生代”,这是因为HotSpot的开发团队将分代收集算法运用到了方法区,但是这并不是必须的。

  • 相关阅读:
    xgzc— math 专题训练(一)
    floyd判圈算法
    CF961G Partitions
    luoguP4778 Counting swaps
    AT3913 XOR Tree(巧妙转换+状压dp)
    手动实现aop编程
    代理模式
    spring重点一:处理对象创建时间 个数以及方式
    spring helloword
    spring用来干什么,解决的问题
  • 原文地址:https://www.cnblogs.com/Java-Script/p/11090254.html
Copyright © 2020-2023  润新知