栈区:
每个线程都包含了一个栈区,栈区中只保存基本数据类型的值和对象的引用以及基本数据类型的引用。
每个栈中的数据(基本数据类型和对象的引用)都是私有的,无法和其他栈共享使用
栈区可以分为三部分:基本类型变量区,执行环境上下文,操作指令区(存放操作指令)
方法区:
为称之为静态区。和堆区一样,被所有的线程共享。
静态变量,常量,类信息(构造方法,接口定义)存放在方法区中。但是实例变量存在堆内存中和方法区无关。
总结来说方法区存储的东西有:static,final,Class,常量池
堆区:
存储的全部都是对象,每个对象包含一个与之对应的class类信息
jvm只有一个堆区。所以它被所有的线程共享。
堆的详解
堆空间:新生代 老年代 元空间
新生代:几乎所有的对象刚创建的时候都在新生代中 伊甸园 存活区
老年代:长久使用的对象
元空间:存储方法运行的时候的临时对象 JDK8以后不在占用JVM内存,占用的是物理内存
GC主要的活动范围就是新生代
gc的流程:
1.当产生一个新的对象的时候,JVM需要为该对象申请内存空间
2.首先判断Eden中是否有内存空间,如果有直接把新对象保存在Eden中
3.如果Eden区内存不足,会自动执行gc操作。将Eden中无用的内存空间清理出来
4.清理Eden去后会再次判断,如果充足在新对象保存在Eden
5.如果gc清理后判断内存依然不足,那就判断存活区是否有内存,把Eden中活跃对象转移到存活区中
6.转移之后 继续判断Eden是否有内存空间,如果有直接存储在Eden
7.如果还是没有判断老年代中的老年区是否有空间,有把存活区中的活跃对象转移到老年代中,将Eden区的活跃对象转移到存活区
8. 一系列转移完成后,再判断Eden是否有内存空间。有 存储。如果还没有则执行老年代的GC。
9. 清理完老年代后依然没有内存进行存储那么则OutOfMemoryException异常
注意:每个内存的子模块都带有一个伸缩区。 伸缩区就是内存不够用的时候,临时使用。当内存存在空余的时候再释放内存。
堆只有一个,所有的线程共享一个堆
方法区详解
方法区:又叫静态区。 里面存储的是class文件的文件信息(包含了方法) , 常量池.
Java程序在运行的时候,首先会通过类加载器载入文件的字节码信息。经过分析之后把分析后的信息存储在方法区中。类的各种信息(类中的方法)都存储在方法区中
创建多个对象会在堆中产生多个对象的内存空间,但是多个对象指向的方法是同一个(就是方法区中的方法)