1。栈(本地虚拟机栈): 里边对应一层层的栈帧, 每个栈帧用来存储一个方法的局部变量表和操作数栈, 方法返回地址等信息。
2.堆: 存储new出来的对象, new出来的数组。 对象中还会维护一个指向对象所属类的指针,方便知道当前这个对象是由哪个类创建的
3.方法区:
JDK1.6及1.6之前 sun的hostspot虚拟机用的是永久代方式实现的,
里边存了: 静态变量、字符串常量池、方法信息(方法的名称、返回值、参数数量及类型、方法的字节码信息、局部变量表信息,操作数栈信息)、从class字节码文件加载的类的相关信息<类的全限定名,类的直接父类名称,修饰符,直接接口的一个有序列表.
需要注意的是使用final修饰的静态变量称为全局常量,在编译的时候就会被分配了。
在逻辑上是属于堆的一部分。其物理内存也都
是可以是不连续的,大小可以指定或者动态扩展。
JDK 1.7时,方法区也被称为永久代,但是开始准备逐渐去除掉永久代了,
此时静态变量、字符串常量池移动到了堆空间中(因为他们使用很频繁,放在方法区中基本不会回收容易导致oom,放在堆中在full GC时会被回收)
(方法区中存储了方法信息、从class字节码文件加载的类的相关信息<类的全限定名,类的直接父类名称,修饰符,直接接口的一个有序列表,>)
JDK1.8及1.8之后 方法区采用了元空间方式实现(采用了计算机直接内存)(其他的没变),
此时静态变量、字符串常量池移还被保留在了堆空间中
(方法区中存储了方法信息、从class字节码文件加载的类的相关信息)
方法区的垃圾回收主要回收常量池中废弃的常量和不再使用的类型。
方法区的垃圾回收主要回收常量池中废弃的常量和不再使用的类型。
常量池中的常量主要存放两大类常量,一类是字面量,一类是符号引用,只要常量池中的常量没有被任何地方引用就会被回收,这与堆空间的对象回收相似。而回收不再使用的类型比较苛刻,必须保证这个类所有的对象实例都已经被回收,并且加载这个类的类加载器也已经被回收,还有就是这个类对应的Class对象没有在任何被引用,满足这三个条件这个类才允许被回收,注意,是允许,并不代表一定会回收,由此可见方法区想要进行垃圾回收十分困难。
推荐博文: 8张图 让你明白 Java内存区域 - 知乎 (zhihu.com)
https://zhuanlan.zhihu.com/p/297001119
Java内存区域详解(万字总结!一篇入魂!点赞收藏!)_煎丶包的博客-CSDN博客推荐博文: Java内存区域详解(万字总结!一篇入魂!点赞收藏!)_煎丶包的博客-CSDN博客
https://blog.csdn.net/qq_39794062/article/details/120100443
13 张图解 Java 中的内存模型 - 知乎 (zhihu.com)
https://zhuanlan.zhihu.com/p/208249150
Java内存模型(JMM)总结 - 知乎 (zhihu.com)
https://zhuanlan.zhihu.com/p/29881777