Java中的内存管理:简介

更新时间: 2024-07-24 09:49:17来源: 粤嵌教育浏览量:943


Java中,内存管理是由Java虚拟机和一个不需要明确干预的。作为一种块结构语言,Java使用一种模型,它的内存分为两种主要类型堆栈和堆。

 

局部变量和方法参数使用基于堆栈的内存当进入或退出代码块或方法时,这部分内存会自动增长和收缩。在向系统请求一定数量的内存的情况下,内存的大小只有在运行时或创建对象时才知道,这些请求通常由进程内存中称为动态内存的区域来满足。严格地说——有这样一种情况,一个可能被指定为堆的对象被写入堆栈

 

这两个存储区描述如下:



图一:JVM堆栈和堆内存区域

*方法参数和局部变量所在的位置

**对象所在的位置

注意一个程序中的所有线程都有自己的堆栈,但是共享一个堆。线程也可以有自己的小堆缓冲区,称为线程本地分配缓冲区(TLAB)

 

这种动态堆内存的问题是,当程序使用完内存时,必须释放内存。如果没有这一点,进程的大小将会增长,直到达到没有更多可用内存资源的程度。为了帮助解决这个问题,当堆内存耗尽,程序不再需要某个对象时,Java中的对象会被一组线程回收内存,这些线程执行一项任务,称为垃圾收集

 

简而言之,程序员不需要担心在Java中释放内存。

虽然这个过程在Java中是自动的,但这并不能保证最佳的系统性能。通过理解Java中内存管理过程的工作方式,您可以更加同情JVM,并调整您的对象创建方法,以便减少JVM和垃圾收集器的负载,从而获得轻微的性能提升。

 

除了垃圾收集,理解Java内存管理的一部分是掌握对象分配的过程因此,本文旨在探索这是什么,并为对象分配提供一个类比。通过理解它是什么以及它在内存管理中的作用,您可以更好地分析对象分配对系统性能的影响。

 

对象分配和垃圾收集

Java中,引用用于访问对象,对象是保存内存区域地址的变量,对象的属性将存储在内存区域中。这个内存被分配给堆区域。当您声明字段或局部变量时,这只是对堆上对象的引用,而不是对象本身。当创建一个对象时,从堆中请求所需的内存量,然后可以通过引用变量访问这个对象。

注意,只要一个对象是可到达的,它就是活的,垃圾收集器不能破坏它。当一个对象不再可达时,这个内存就有资格被垃圾收集器回收用于堆。这里值得澄清的是可达性的概念。一个对象的引用必须可以从一个叫做根集的地方到达,如图2所示。根集包括当前所有线程堆栈上的所有局部变量和方法参数。如果两个对象相互引用,但是根集不能到达,它们将被垃圾收集。



图二对象可达性

 

对象创建和销毁之间的时间由术语对象生命周期概括,对于短命对象,这些对象保留在堆内存的一部分,称为“Nursery;这也被称为年轻空间伊甸园。对于寿命较长的对象,通常会将其移动到堆中称为“Tenured”旧空间)的部分,以便腾出Nursery来分配新对象。值得一提的是,在大多数程序中,创建的大多数对象都是短暂的;换句话说,它们被创造和释放得相对较快,所以它们永远不会到达终身空间。在任何情况下,垃圾回收通常发生在需要释放更多内存时。托儿所是分配更多对象的地方。这些通常是短暂的,而且由于它通常是一个较小的区域,清理Nursery比清理终身空间要快得多。


很重要的一点是,要么将生命周期短于两次新收集之间的时间的短生命周期对象作为目标,要么将它们作为终身空间中的程序生命周期的目标,因为这样可以减少整个应用程序的开销。在这种情况下,对象分配非常低,堆大小适合系统,垃圾收集很少发生,不会影响应用程序的运行,这是我们在Chronicle中的目标。




3:JVM堆中的Nursery空间和Tenured空间

 

简而言之,当在类中声明字段和局部变量时,只为引用分配足够的内存。无论对象本身的大小如何,引用通常是每个对象48个字节,对象本身被分配在堆上的其他地方。对象分配是分配对象内存的过程,对象内存是在使用“new”运算符时分配的。


结论

本文介绍了Java中的内存管理,以及对象分配的简单类比,并说明了考虑它的重要性。让JVM有效地管理动态内存是确保最佳系统性能的基础。


免费预约试听课