不同于C++需要编程人员手动释放内存,Java有虚拟机,因此Java不需要程序员主动去释放内存,而是通过虚拟机自身的垃圾回收器(Garbage Collector-GC)来进行对象的回收。Java语言由于有虚拟机的存在,实现了平台无关性,在任意平台都是通过将代码转换为字节码文件,从而在平台下的虚拟机中运行代码的。
JVM内存区域分布
虚拟机栈:存放每个方法执行时的栈帧,一个方法调用到完成就对应栈帧在虚拟机栈中入栈和出栈的过程。
本地方法栈:和虚拟机栈类似,不过是为Java中native方法服务的。平时所说的“栈内存”指的就是虚拟机栈和本地方法栈的合称。
程序计数器:当前线程执行字节码的行号指示器,字节码解释器工作依赖于它。占用较小的内存空间,不会出现OOM。
堆:即所谓的“堆内存”。JVM所管理最大的一块内存,被所有线程共享。唯一作用就是给对象实例分配内存空间,在分代回收算法中的新生代老年代就在于堆中。
方法区(也称为永久代):不在堆中,被各个线程共享,存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。其中包括常量池。
另:直接内存,不属于JVM内存区域,与NIO联系紧密,不受JVM内存大小限制。
JVM垃圾回收机制
-
何时进行垃圾回收?
GC本质上是一道守护进程(Daemon Thread),不停的检测堆中是否有不可达对象并释放内存,因此GC在何时发生其实我们是无法预测的。GC通过调用对象的finalize()方法来摧毁对象。
-
回收谁?
GC回收堆中的不可达对象。
不可达对象的判定:根搜索算法。JVM中有一系列设定的GC Roots,当一个对象到任意一个