java 内存模型

JVM 内存结构和java内存模型

Posted by 果然 on May 6, 2022

在java开发中,经常被问到:JVM和java内存模型等问题。还可能会碰到OOM和StackOverflowError等错误。本篇对JVM内存结构和java内存模型知识进行简单汇总。

JVM内存结构和Java内存模型

JVM

JVM 的内存结构大概分为:

  • 堆(heap):线程共享。所有对象实例及数组都要在堆上分配。回收器管理的对象。
  • 方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。
  • 方法栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。
  • 本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的native方法服务。
  • 程序计数器(program counter register):线程私有。可看作是当前线程所执行的字节码的行号指示器,指向下一条要执行的指令。

JVM 内存结构的布局和相应的控制参数

jvm parameter

JVM 内存结构 控制参数 垃圾回收
-Xms 设置堆的最小空间大小。-Xmx 设置堆的最大空间大小。-XX:NewSize 设置新生代最小空间大小。-XX:MaxNewSize 设置新生代最小空间大小。 此区域为垃圾回收的主要操作区域
方法区 -XX:PermSize 设置最小空间。 -XX:MaxPermSize 设置最大空间 很少进行垃圾回收
方法栈 -Xss 控制线程栈大小  
本地方法栈 在Sun JDK中本地方法栈和方法栈是同一个,因此也可以用-Xss控制每个线程的大小。  

java 内存模型

java 线程间的通讯由Java 内存模型(JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。

堆内内存

堆内内存 = 新生代 + 老年代 + 持久代
对象的堆内存由称为垃圾回收器的自动内存管理系统回收。堆的内存不需要是连续空间,因此堆的大小没有具体要求,即可以固定,也可以扩大和缩小。

JVM-对外内存详解

对外内存就是将内存对象分配在java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机),这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响。
那么,堆外内存是如何申请和释放的呢?

祭出大杀器了:DirectByteBuffer

JDK中使用DirectByteBuffer对象来表示堆外内存,每个DirectByteBuffer对象在初始化时,都会创建一个对应的Cleaner对象,这个Cleaner对象会在合适的时候执行unsafe.freeMemory(address),从而回收这块堆外内存。