在java编写的过程中,程序员不需要像C++那样为内存管理煞费苦心,因为jvm帮助我们处理好了内存的管理,但是在jvm中,是怎样来处理内存的呢,让我们看看jvm对内存的分类。jvm中的运行时数据区分为两大类:线程之间共享的数据区和线程之间不共享的数据区。
线程共享数据区:
-
方法区:用于存放被jvm加载的类型信息、常量、静态变量、编译后的代码缓存等。垃圾回收的主要目标是常量池和类型的卸载。
-
堆:用来存放对象实例以及数组(不一定所有的对象都存放在堆里面)。由于在运行时,jvm的垃圾清理工作都发生都在堆中,所以又叫作“GC堆(Garbage Collected Heap)”。堆内存又被分为新生代、老年代、永久代(永久代在jdk8之后被改造成“元空间”)。而新生代又被划分成“Eden区”、“From Survivor区”、“To Survivor 区”。(为了配合GC算法,采用的是标记-复制算法)其中一般所说的轻GC发生在新生代、Full GC 则发生在新生代和老年代。
线程私有的数据区:
- 虚拟机栈:用于记录和存储java方法执行的线程内存模型,一个方法对应一个栈帧,栈顶的方法表示正在运行的方法。有了逃逸分析后,如果一个对象的使用范围只在本方法里的话,那么这个对象是可以放在栈里面的。
- 本地方法栈:用于处理本地(native)方法。有的虚拟机将其和虚拟机栈合二为一,例如:HotSpot虚拟机。
- 程序计数器:存储的是程序运行时代码的运行顺序。