Java虚拟机运行时数据区域

java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的。
相对处理器的一个内核,任何时刻只执行一条线程。

  • 程序计数器(Program Counter Register)
    当前线程执行到的字节码的行号指示器,是一块较小的内存空间,每条线程独立存储或不干扰。
    每个线程私有。
    不会抛出OutOfMemoryError。
    执行native方法时值为空。
  • java虚拟机栈(Java Virtual Machine Stacks)
    java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储方法运行时的基础数据结构包括局部变量表、操作数栈、动态链接、方法出口等信息;每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
    每个线程私有,生命周期与线程相同。
    会抛出OutOfMemoryError(虚拟机栈动态扩展时没有足够的内存)和StackOverflowError(虚拟机栈深度大于允许值,通常1000---2000)。
  • 本地方法栈(Native Method Stack)
    与java虚拟机栈类似,为虚拟机使用到的Native方法服务。
    每个线程私有。
    会抛出OutOfMemoryError和StackOverflowError。
    部分虚拟机将本地方法栈和java虚拟机栈合二为一。
  • Java堆(Java Heap)
    存放对象实例,几乎所有的对象实例都是在这里分配内存包括数组。
    所有线程共享的一块内存区域,随虚拟机启动时创建。
    会抛出OutOfMemoryError(没有内存分配实例,并且无法再扩展时)。
    可以处于物理上不连续的内存空间,只要逻辑上连续,既可以是固定大小,也可以是可扩展的。
  • 方法区(Method Area)别名非堆(No-Heap)或永久代(Permanment Generation)
    用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
    所有线程共享。
    会抛出OutOfMemoryError(无法满足内存分配需求时)。
    可以处于物理上不连续的内存空间,只要逻辑上连续,既可以是固定大小,也可以是可扩展的;同时可以选择不实现垃圾收集。
  • 其他介绍
    (1)运行时常量池(Runtime Constant Pool)时方法区的一部分
             主要用于存放编译期生成的各种字面量和符号引用(在类加载后进入常量池),还有翻译出来的直接引用和运行期间产生的新常量。
             会抛出OutOfMemoryError(无法满足内存分配需求时)。
    (2)直接内存(Direct Memory)
             使用Native函数库直接分配的堆外内存。通过java堆上的DirectByteBuffer对象作为这块内存的引用进行操作。
             会抛出OutOfMemoryError(当各个内存区域总和大于物理内存限制包括物理的(RAM、SWAP、分页文件)和操作系统的限制,从而导致动态扩展失败)。
    java虚拟机运行时数据区域.png

    shuju.png
内存分配

-Xms最小堆容量
-Xmx最大堆容量,
-Xss栈容量,
-XX:PermSize 方法区容量
-XX:MaxPermSize 最大方法区容量
-XX:MaxDirectMemorySize 最大直接内存容量
系统限制内存减去最大堆容量,再减去最大方法区容量;程序计数器消耗内存很小,可以忽略以及虚拟机内存不计,剩余的由虚拟机栈和本地方法区以及直接内存瓜分。
每个线程分配的栈容量越大,可以建立的线程数量就越少,建立线程时越容易把剩余的内存耗尽。

你可能感兴趣的:(Java虚拟机运行时数据区域)