Java :初识Java内存管理

it2022-05-05  151

0, 说明

       最近在看与Java相关的代码时,遇到了一些Java内存管理的问题。想起以前学习Java时,只是简单的学习了面向对象的语法,对于Java的内存管理只是简单的了解一下,此次查了一些资料,对Java的内存管理进行了学习,这篇博文主要是记录学习笔记。若后面有进一步学习JVM,则会继续更新。        如果文章中存在错误,或者描述不当,请大佬不吝赐教。 (^ - ^ )

1, Java的内存形式

       Java中的内存有多种存在的形式,不同形式的内存有不同的功能。其中包括了Method Area, Java Stack Memory, Java Heap Memory, PC Registers, Native Stack Memory(即C Stack), 下面简单地对这些名词进行说明,更具体的说明可以参见[1][3][4]。

       1, Method Area : 这一块内存区域主要用于存放编译后的代码,以及常量池,类的名字,方法等,所有的JVM Thread都共享这一块区域。

       2, Java Stack Memory : Java程序执行时所使用的内存区域,每一个JVM Thread都有自己的Stack Memory。 其访问方式是FIFO,并且访问速度快于Java Heap Memory。

在调用一个方法时,首先会将参数等压入Stack Memory, 在方法执行过程中,内部的临时变量会随着时间不断地压入栈,弹出栈。 最后在方法结束时,会将返回值存放在栈中,以便其他程序能够获取返回值。

       3, Java Heap Memory : 这一块区域主要是用于在程序运行的过程中,动态地为对象和类分配内存空间,这一块区域由JVM Thread共享,由于其存在竞争,故访问速度慢于Stack Memory. 并且heap memory需要GC进行回收。其主要分为以下空间:

1), Eden Space : 这一块空间用于存放新分配的对象。 2), Survivor Space : 在进行垃圾回收后,Eden Space中尚未回收的对象会被移动至这一块空间。 3), Tenured Space : 经过若干次(次数和Java Virtual Machine的实现相关)垃圾回收后,若某些对象仍然存活,则会被启动到这一块空间。

       4, PC Registers : 每一个Java Thread都会有自己的PC Register, 用于记录当前Java Thread执行指令的地址。

       5, Native Stack : 由于JVM底层实现时会使用一些本地的方法,这些本地方法在执行时会将信息存放在Native Stack中。

2, Java Reference类型

       Java采用了Garbage Collector对内存空间进行管理,在对GC进一步介绍之前,先简单的介绍一下Java中各种Reference。

       Java中主要包含四种Reference, 分别为Strong Reference, Week Reference, Soft Reference, Phantom Reference。关于这四种Reference的说明,详细可以参见[4]。下图是对这四种Reference的一个简单的总结。

3, Java Garbage Collector类型

       Java中包含多种不同的GC, 垃圾回收线程的每一次启动是由Java虚拟机确定的,用户也可以执行System.gc()来启动垃圾回收线程,但是下面的假设是错误的[4] :

代码执行到System.gc()时,一定会启动垃圾回收线程。

       执行System.gc()只能说明通知了Java启动一次垃圾回收,但是其启动的时间仍然由Java确定。

       Java中主要包含4中GC,分别是Serial Garbage Collector, Parallel Garbage Collector, G1 Garbage Collector, Concurrent Mask Sweep(CMS) GC。其中除了Serial GC以外,其他都是采用多线程方式来实现的。关于这些不同GC的说明,详细可以参见[4][6]。        下图是对这四种Garbage Collector的一个简单的总结。

4,Java内存管理

       Java中使用GC管理内存,在程序执行的过程中,对于新创建的对象,其存放的内存空间为Heap Memory的Eden Space, 在一次垃圾回收的线程执行完毕后,没有被引用的对象将被回收掉,释放其所占据的内存空间。仍然被引用的对象会被移动到Survivor Space. 若某些对象在若干次垃圾回收后仍然存在,则对象被移动到Tenured Space。

5,总结

       本文简单的记录了Java的内存空间管理,并总结了不同形式的Object Reference和Garbage Collector。如果后面时间有时间的话,将会花费一些时间拜读一下JDK的垃圾回收机制的源代码。

6,引用

[1] https://www.baeldung.com/java-stack-heap [2] https://www.baeldung.com/jvm-parameters [3] https://www.baeldung.com/jvm-vs-jre-vs-jdk [4] https://dzone.com/articles/java-memory-management [5] https://stackoverflow.com/questions/3571203/what-are-runtime-getruntime-totalmemory-and-freememory [6] https://www.baeldung.com/jvm-garbage-collectors


最新回复(0)