JVM内存大概分为几块区域:堆、栈、程序计数器、MetaSpace元空间、直接内存区,见下图
线程级内存区域:栈、程序计数器,堆与操作系统一样多个线程共享。
本地方法栈是和虚拟机栈非常相似的一个区域,它服务的对象是 native 方法。你甚至可以认为虚拟机栈和本地方法栈是同一个区域
Java虚拟机栈中存放的是栈帧(Frame),而运行的每个方法都会产生一个栈帧,最后执行的方法栈帧在栈顶,所以是FILO。一个栈帧中包含:
线程级别内存,程序计数器存储了当前正在运行的流程,包括正在执行的指令、跳转、分支、循环、异常处理等,简单理解为记录当前线程执行字节码的行号的区域。
堆是 JVM 上最大的内存区域 ,多线程共享区域,我们经常说一个变量是非线程安全的,那这个变量一定就存放在堆里面, 堆也是GC的重点对象。
一个对象创建的时候,到底是在堆上分配,还是在栈上分配呢?这和两个方面有关:对象的类型和在 Java 类中存在的位置。Java 的对象可以分为基本数据类型和普通对象
当在方法体内声明了基本数据类型的对象,它就会在栈上直接分配。其他情况,都是在堆上分配。
像 int[] 数组这样的内容,是在堆上分配的。数组并不是基本数据类型
存放类的信息、常量池、方法数据、方法代码等,元空间属于堆外内存,-XX:MaxMetaspaceSize 来控制大小。这里解释下:方法区是JVM规范中的一个逻辑概念,在Java8之前叫永久代(Perm Area) , 可以理解为 Java8 之前方法区的实现是永久代,Java8 之后是元空间。
原文:https://www.cnblogs.com/lihuamaoa/p/13291220.html