Java多线程——JVM内存区域

Java Virtual Machine=JVM 虚拟机的内存空间:

Java多线程——JVM内存区域_第1张图片

分别是:

1. 堆

2. 方法区

3. 线程私有区


先介绍线程私有区: 这里说的线程私有区,顾名思义,就是多线程中各个线程独立使用的内存空间,包括:

程序计数器:

  • 在多线程编程中,存在上下文切换的现象(每条线程用完自己的时间片后,即使任务还没完成,操作系统也会剥夺它的执行权,让另一条线程执行),为了记录当前线程执行的代码行号、指令地址,诞生了程序计数器。

  • 指向当前线程正在执行的字节码指令的地址、行号。

  • 这块内存不会进行GC,即不存在OutOfMemoryError。

  • 与线程同生命周期

Java 虚拟机栈:

  • 描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表操作栈动态链接方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
  • 与线程同生命周期
  • Java 虚拟机栈中有一个局部变量表,在方法被执行的时候被创建,存放了编译期所能知的各类基本数据类型,对象引用例如:Person p=new Person();存的是p(引用变量)。 double 和long会占用2个局部变量空间,其余的占用1个。
  • 局部变量表的大小在编译时期就确定下来了,在创建的时候只需分配事先规定好的大小即可。此外,在方法运行的过程中局部变量表的大小是不会发生改变的。

堆:

  • 最大的一块内存,在JVM启动的时候创建这块内存
  • 包含两个大部分,新生代和老年代(1:2),新生代中包含Eden区,From Survivor和To Survivor,比率为8:1:1,这样分配的目的是为了更好地进行GC
  • 几乎所有的对象的实例都存放在这里

方法区:

  • 在Java8.0被替换为MetaSepace
  • 存放 已经被虚拟机加载类信息、常亮、静态变量
  • 在HotSpot虚拟机上被称为“永久代”

本地方法栈:

  • 与Java栈的区别在于,执行的是Native方法(非Java方法)
  • Sun hotspot虚拟机直接把本地方法栈和Java栈合二为一

直接内存:

  • 不属于虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是也被频繁使用,而且也可能导致OutOfMemoryError
  • JDK引入NIO类,引入一种基于通道Channel与缓冲区Buffer的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样能显著提高某些场景的性能,避免Java堆和Native堆的来回复制
  • 直接内存的分配不会受Java堆大小的限制,但是肯定还是受本机总内存大小、处理器寻址空间的限制,所以在配置虚拟机参数的时候,除了根据实际内存配置-Xmx等参数,还得注意直接内存

转载于:https://my.oschina.net/u/4120078/blog/3040306

你可能感兴趣的:(Java多线程——JVM内存区域)