java从堆分配空间的速度,可以喝其他语言从堆栈上分配空间的速度相比。
C++语言的堆看做一个院子,每个对象都有自己的一块地盘。一段时间后,对象可以被销毁,但是地盘当然需要重用。JVM中不同:它更像一个传送带,每分配一个新的对象,就往前移动一格,这样对象分配速度快。java“堆指针”只是简单的移动到尚未分配的区域,与C++在堆栈上的分配速度。当然,在实际的过程中,簿记工作方面会有商量额外的开销,但是相比查找可用空间这样很小了。
你可能已经意识到,其实java中的堆未必完全是像传送带那样工作。因为这样的话,会导致频繁的内存页面调度——将其移进、出硬盘,并因此显得需要拥有比实际需要更多的内存。页面调度会显著的影响性能,最终在创建足够多的对象后,内存资源耗尽。因此,这里就多了jvm的核心关键:垃圾回收器。
垃圾回收器工作时候,将一面回收空间,一面使堆中的对象紧凑排列。这样的“堆指针”就很容易移动到更接近“传送带”的开始处,也就尽量避免了页面错误。通过垃圾回收器对对象的重新排列,实现了一种高速的、有足够空间可供分配的堆模型。
我们先看看其他语言的垃圾回收机制:引用计数是一种简单但是速度很慢的垃圾回收技术。对个对象都含有一个引用计数器,当有引用连接对象时,引用计数+1,,当引用离开作用于或者被设置成为null时,引用计数-1,。虽然管理引用计数的开销不大,但是这是一个在整个程序的生命周期中一直持续着。垃圾回收器会在所有的对象列表上遍历,当发现某个对象的引用计数0,就释放其占用的空间(这样的机制,导致一旦计数为0就会立即释放对象资源),这样的方法有个明显的缺陷,就是如果对象之间存在循环引用,可能出现“对象英爱被回收但是引用计数不为0”。对垃圾回收期而言,要定位这样的交互自引用的对象组,又是一个大量的开销。引用计数常用来说明垃圾回收器的垃圾收集方式,但却未被任何垃圾回收器使用。
在更通用的模式中,垃圾回收器并非基于引用计数技术。中心思想:对任何“活”的对象。一定能够追溯到让其存活的在堆栈或者静态存储区的引用。这个引用链条可能会穿过数个对象层次。由此,如果从堆栈或者静态存储区开始,便利所有引用,就能找到所有“活”着的对象。对于发现的引用,必须追踪它所引用的对象,然后是此对象包含的所有的引用,如此迭代下去,直到找到所有“根源于堆栈和静态存储区的引用”所形成的网络被全部访问为止。你所访问过的对象,理所当然应该都是“活”的。这样就解决了“交互自引用的对象组”的问题——这种现象根本不会被发现,因此自动回收。
在这种思想下,Java虚拟机将采用一种“自适应”回收技术。至于如何处理找到的这些存活对象,就取决于java虚拟机的实现。
1.停止-复制(stop-and-copy)
这意味着先暂停程序的运行(不属于后台回收模式),然后将所有的“活”对象从当前堆复制到另一个新堆。没有被复制的就是垃圾了,回收。当对象被复制到新堆后,它是一个接着一个紧凑的直接按照前面方法,简单直接分配内存。
当堆乡从一处搬到另一处,所有指向它的引用必须修正,位于堆或者静态储存区的可以自行修正,但可能还有其他指向这些对象的引用,他们在遍历使用时,才能动态的被找到。(旧地址-新地址的映射)
缺点:“复制式”GC效率会降低,1)首先要得到两个堆,2)在这两个堆间的分离来回操作,得维护比实际需要更多一倍的时间,3)复制:程序进入隐性状态后,可能只有很少的垃圾,甚至没有垃圾产生,但是GC仍然会将所有的内存从一处-另一处新堆,浪费。
Java处理:1)按照需要从堆中分配几块较大的内存,复制动作发生在这些较大内存间,减少创建新堆。2)
JVM检查:要是没有新垃圾,就会转换到新模式(自适应),这种模式称为标记-清扫(mark-and-sweep)
3.标记-清扫(mark-and-sweep)
依据思路仍然是从堆栈或者静态存储区出发,遍历所有引用,找出所有“活”对象,每当它找到或对象,就会给对象标记,这个过程不会回收任何对象。
全部标记完成后,清理才开始,没有被标记的对象就是GC,北释放内存,没有复制操作。
缺点:这样做后,剩下的内存空间显然不是连续的,要想连接,需要重新整理。而且这种模式速度慢。
Java GC theory:
以上两种思路,都是在暂定程序情况下进行的。
前文所述,当前Java VM中,内存分配以较大”块“为单位,如果对象较大,会占用单独的块。严格地说,定制-复制要求释放就对象之前,必须把所有存活的对象从旧堆中复制到新堆,这会导致大量的copy块,GC回收时候就可以网废弃块中COPY。
每个块都有相应代数(generation count)记录它是否存活,通常,块在某处被引用,就会代数+1,GC将上次回收动作之后新分配的块进行管理,这对处理大量短命临时的对象尤其有效。
GC定期进行完整清理动作,大型对象仍然不会被复制(代数+1),内含小对象的那些块被复制,整理。JVM会监视:所有对象都很稳定,GC效率低,切换”标记-清扫“模式,同样的,JVM跟踪该模式的效果,如果发现大量碎片,重回“停止-复制”模式。
自适应技术:自适应的、分代的,停止-复制,标记-清扫式GC。
相关推荐
### Java GC垃圾回收调优指南 #### 概述 在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。合理的GC配置可以显著提高应用程序的性能和稳定性。本指南旨在帮助开发者深入理解...
本文将详细介绍Java中的垃圾回收机制及其工作原理,并探讨JVM如何管理和优化垃圾回收过程。 #### 二、JVM内存模型 JVM内存模型主要包括永久代(Permanent Generation, PermGen)、堆(Heap)和栈(Stack)三大部分。值得...
本文将详细介绍Java垃圾回收机制的工作原理、各个阶段的执行过程、不同的垃圾回收器类型、Java中的引用类型等。 Java垃圾回收机制的工作原理 ------------------------- Java垃圾回收机制的工作原理是,当一个对象...
GC-powerstation 9.1.2可能提供了更高效的垃圾回收算法、更好的性能监控、更精细的调优选项,或者对特定JVM(Java虚拟机)版本的支持。 PowerPlatform_oldEnglish这个文件名可能指的是该版本的文档或资源库,其中...
在C++中,内存管理主要依赖于程序员手动分配与释放,而在Java中,垃圾回收器自动处理这一过程。当一个对象不再被任何引用所指向时,它就被认为是“垃圾”,即可以被回收的对象。垃圾回收器会周期性地运行,识别并...
开发者需要掌握垃圾回收机制的工作原理、垃圾回收算法和垃圾回收器的选择,以及如何进行调优和优化,以提高程序的性能和稳定性。同时,还需要注意避免内存泄漏和内存溢出等问题的发生,确保程序的健壮性和可靠性。
如果一个对象没有任何引用指向它,那么这个对象就可以被视为垃圾,并可被垃圾回收器回收。 #### 三、Java中的垃圾回收器 ##### 3.1 Serial Collector Serial Collector是最简单的垃圾回收器,它只使用单线程进行...
Java的自动内存管理机制是其一大亮点,尤其体现在垃圾收集(Garbage Collection, GC)方面。GC能够自动地识别不再使用的对象,并释放其占用的内存空间,从而避免了手动管理内存所带来的潜在问题。本文将深入探讨Java...
GC,java的垃圾会回收机制的原理
4. G1 GC:新一代的垃圾回收器,目标是达到低延迟,通过分区技术来平衡吞吐量和暂停时间。 5. ZGC:最新一代的低延迟GC,目标是在大内存环境下实现极低的暂停时间。 四、垃圾回收的过程 GC主要包括三个阶段:标记、...
本文将深入对比Java与C#这两种广泛使用的编程语言中的垃圾回收机制,帮助开发者更好地理解它们的工作原理以及差异。 #### 二、Java的垃圾回收机制 ##### 2.1 Java内存区域 Java虚拟机(JVM)将内存划分为几个主要...
【JAVA·初级】GC垃圾回收机制是Java编程中一个至关重要的概念,对于任何Java开发者来说,理解并掌握这一机制都是提升程序性能的关键。在Java中,内存管理主要依赖于垃圾回收器(Garbage Collector,简称GC),它...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项至关重要的机制,它自动管理内存,释放不再使用的对象,防止内存泄漏。本篇将深入探讨如何监控Java的垃圾回收,帮助开发者提升应用性能和稳定性。 Java...
Java垃圾回收器(Garbage Collector, GC)是Java编程语言中的一个重要特性,它负责自动管理内存,自动回收不再使用的对象,以防止内存泄漏。在Java中,程序员无需手动释放内存,这一过程由JVM(Java虚拟机)自动完成...
本文将深入探讨Java中的垃圾回收机制,包括其工作原理、常用算法以及实际应用中的注意事项。 #### 二、垃圾回收的基本概念 **1. 什么是垃圾回收** 垃圾回收(Garbage Collection, GC)是指在程序运行过程中自动...
垃圾回收器通过确定哪些对象不再被引用(即GC Roots不可达),来释放不再使用的内存空间。GC Roots包括:虚拟机栈中的本地变量、方法区的类静态变量、全局引用(如JNI本地方法的引用)等。垃圾回收器会定期检查这些...