Java内存管理
本文将重点介绍Java内存管理、堆的工作原理、引用类型、垃圾收集以及相关概念。
为什么要学习Java内存管理?
我们都知道, Java自己管理内存,不需要程序员的显式干预。垃圾收集器本身可确保清理未使用的空间,并在不需要时释放内存。那么程序员的角色是什么,为什么程序员需要学习Java内存管理?作为一名程序员,您不需要为诸如销毁对象之类的问题而烦恼,这一切都归功于垃圾收集器。然而,自动垃圾收集并不能保证一切。如果我们不知道内存管理是如何工作的,那么我们通常会遇到一些不受 JVM(Java虚拟机)管理的东西。有些对象不符合自动垃圾回收的条件。
因此,了解内存管理是必不可少的,因为它将有利于程序员编写不会崩溃的基于高性能的程序,或者如果这样做,程序员将知道如何调试或克服崩溃。
介绍:
在每种编程语言中,内存都是至关重要的资源,而且在本质上也是稀缺资源。因此,必须彻底管理内存而没有任何泄漏。内存的分配和释放是一项关键任务,需要非常小心和考虑。然而,在Java中,与其他编程语言不同,JVM 以及特定的垃圾收集器具有管理内存分配的作用,因此程序员不需要这样做。而在其他编程语言(例如 C)中,程序员可以直接访问在其代码中分配内存的内存,从而为泄漏创造了很大的空间。
Java内存管理中的主要概念:
- JVM内存结构
- 垃圾收集器的工作
Java内存结构:
JVM 定义了在程序执行期间使用的各种运行时数据区域。有些区域是由 JVM 创建的,而有些是由程序中使用的线程创建的。但是,JVM 创建的内存区域只有在 JVM 退出时才会被销毁。线程的数据区在实例化时创建,在线程退出时销毁。
让我们详细研究一下内存区域的这些部分:
堆:
- 它是一个共享的运行时数据区,并将实际对象存储在内存中。它在虚拟机启动期间被实例化。
- 此内存分配给所有类实例和数组。堆可以是固定大小或动态大小,具体取决于系统的配置。
- JVM 提供用户控制来根据需要初始化或改变堆的大小。当使用新关键字时,对象在堆中被分配一个空间,但相同的引用存在于堆栈中。
- 对于一个正在运行的 JVM 进程,只有一个堆。
Scanner sc = new Scanner(System.in);
上面的语句创建了 Scanner 类的对象,该对象被分配到堆中,而引用“sc”被推送到堆栈中。
Note: Garbage collection in heap area is mandatory.
方法区:
- 它是堆区域的逻辑部分,在虚拟机启动时创建。
- 该内存分配给类结构、方法数据和构造函数字段数据,以及类中使用的接口或特殊方法。堆可以是固定大小或动态大小,具体取决于系统的配置。
- 可以是固定大小或根据计算需要扩展。不需要是连续的。
Note: Though method area is logically a part of heap, it may or may not be garbage collected even if garbage collection is compulsory in heap area.
JVM 堆栈:
- 堆栈在创建线程的同时创建,用于存储在返回方法值和执行动态链接时需要的数据和部分结果。
- 堆栈可以是固定大小或动态大小。堆栈的大小可以在创建时独立选择。
- 堆栈的内存不需要是连续的。
本机方法堆栈:
也称为 C 堆栈,本机方法堆栈不是用Java语言编写的。该内存是在创建时为每个线程分配的。它可以是固定的或动态的。
程序计数器 (PC) 寄存器:
每个执行特定方法任务的 JVM 线程都有一个与之关联的程序计数器寄存器。非本地方法具有存储可用 JVM 指令地址的 PC,而在本地方法中,程序计数器的值是未定义的。 PC 寄存器能够在某些特定平台上存储返回地址或本机指针。
垃圾收集器的工作:
- JVM 触发此过程,并根据 JVM 垃圾收集过程完成或保留。它通过自动执行内存的分配或释放来减轻程序员的负担。
- 垃圾收集过程会导致其余进程或线程暂停,因此本质上是昂贵的。这个问题对于客户端来说是不可接受的,但可以通过应用几种基于垃圾收集器的算法来消除。这个应用算法的过程通常被称为垃圾收集器调整,对于提高程序的性能很重要。
- 另一种解决方案是分代垃圾收集器,它向分配了内存的对象添加年龄字段。随着越来越多的对象被创建,垃圾列表增加,从而增加了垃圾收集时间。根据对象存活了多少时钟周期,对象被分组并相应地分配一个“年龄”。这样垃圾收集工作就会被分配。
- 在当前场景中,所有垃圾收集器都是分代的,因此是最优的。
Note: System.gc() and Runtime.gc() are the methods which requests for Garbage collection to JVM explicitly but it doesn’t ensures garbage collection as the final decision of garbage collection is of JVM only.
了解程序及其数据的存储或组织方式至关重要,因为当程序员打算根据资源和消耗编写优化的代码时,它会有所帮助。它还有助于发现内存泄漏或不一致,并有助于调试与内存相关的错误。但是,内存管理的概念非常广泛,因此必须尽最大努力尽可能地研究它以提高相同的知识。