垃圾回收(GC)一直是Java受欢迎背后的重要特性之一。垃圾回收是Java中用于释放未使用的内存的机制。本质上,它追踪所有仍在使用的对象,并将剩下的标记为垃圾。Java的垃圾回收被认为是一种自动内存管理模式,因为程序员不必指定对象准备被释放。垃圾回收在低优先级的线程上运行。

在本教程中,我们将学习java中内存分配/解除分配有关的各种概念,在场景后面运行的算法以及您必须自定义此行为的选项。

对象生命周期

Java的对象生命周期可以分为三个阶段:

对象创建

要创建一个对象,通常我们使用new关键字。例如

Object obj = new Object();

创建对象时,会分配特定数量的内存用于存储该对象。分配的内存量可以根据体系结构和JVM而有所不同。

对象在使用中

到时候,对象被应用程序的其他对象使用(其他活动对象具有指向它的引用)。在使用过程中,对象驻留在内存中,并可能包含对其他对象的引用。

对象破坏

垃圾回收系统监视对象,并在可行的情况下统计每个对象的引用数量。当没有对象的引用时,就没有办法用当前运行的代码来访问它,所以释放相关联的内存是非常合理的。

垃圾回收算法

对象创建是通过您编写的代码完成的; 以及您用来使用其提供的功能的框架。作为一名Java开发人员,我们不需要取消分配内存或取消引用对象。它由gargabe收集器在JVM级别自动完成。自从Java诞生以来,已经有很多关于在场景后面运行的算法的更新来释放内存。让我们看看他们是如何工作的?

马克和扫描

它是初始和非常基本的算法,分两个阶段运行:

标记活动对象 - 找出所有仍然活着的对象。

删除无法访问的对象 - 删除其他所有内容 - 所谓的死亡和未使用的对象。

首先,GC将一些特定对象定义为垃圾回收根。例如当前正在执行的方法的本地变量和输入参数,活动线程,已加载类的静态字段和JNI引用。现在,GC遍历内存中的整个对象图,从这些根开始,并从根到下一个对象的引用。GC访问的每个对象都被标记为活动。

应用程序线程需要停止标记才能发生,因为如果它不断变化,它不能真正遍历图形。它被称为停止世界暂停。

第二阶段是摆脱未使用的对象来释放内存。这可以通过多种方式完成,例如

正常删除 - 正常删除将未引用的对象移除到空闲空间并保留引用的对象和指针。内存分配器(散列表的种类)持有对可以分配新对象的可用空间块的引用。

它经常被当作mark-sweep算法。

压缩删除 - 仅删除未使用的对象效率不高,因为可用内存块分散在存储区域中,并且如果创建的对象足够大并且未找到足够大的内存块,将导致OutOfMemoryError。

为了解决这个问题,在删除未引用的对象之后,对其余的引用对象进行压缩。这里的压缩指的是将参考对象移动到一起的过程。这使得新的内存分配变得更加容易和快速。

它经常被当作mark-sweep-compact算法。

删除与复制 - 这与标记和补偿方法非常相似,因为它们也会重新定位所有活动对象。重要的区别是重定位的目标是不同的存储区域。

它经常被当作mark-copy算法。

并发标记扫描(CMS)垃圾回收

CMS垃圾回收本质上是一种升级的标记和扫描方法。它使用多线程扫描堆内存。它进行了修改,以利用更快的系统并提高性能。

它试图通过与应用程序线程同时进行大部分垃圾回收工作来尽量减少由于垃圾回收造成的暂停。它使用年轻一代中的并行停止世界标记复制算法和老一代中主要是并发的标记扫描算法。

要使用CMS GC,请使用下面的JVM参数:

-XX:+UseConcMarkSweepGC

CMS GC优化选项

标识

描述

-XX:+ UseCMSInitiating \ OccupancyOnly

表示您希望仅将占用情况用作启动CMS回收操作的标准。

-XX:CMSInitiating \ OccupancyFraction = 70

设置CMS生成占有率以启动CMS回收周期。

-XX:CMSTriggerRatio = 70

这是在MinHeapFreeRatioCMS周期开始之前分配的CMS生成的百分比。

-XX:CMSTriggerPermRatio = 90

设置MinHeapFreeRatio开始CMS回收周期之前分配的CMS永久生成中的百分比。

-XX:CMSWaitDuration = 2000

使用该参数指定允许CMS等待年轻回收的时间。

-XX:+ UseParNewGC

选择使用并行算法进行年轻空间回收。

-XX:+ CMSConcurrentMTEnabled

为并发阶段启用多个线程。

-XX:ConcGCThreads = 2

设置用于并发阶段的并行线程的数量。

-XX:ParallelGCThreads = 2

设置您想要用于停止世界阶段的并行线程的数量。

-XX:+ CMSIncrementalMode

启用增量CMS(iCMS)模式。

-XX:+ CMSClassUnloadingEnabled

如果未启用,CMS将不会清除永久空间。

-XX:+ ExplicitGCInvokes \并发

这允许System.gc()触发并发回收而不是完整的垃圾回收周期。

串行垃圾回收

该算法对老一代的年轻一代和标记扫描压缩使用标记复制。它适用于单个线程。执行时,它会冻结所有其他线程,直到垃圾回收操作结束。

由于串行垃圾回收的线程冻结性质,它只适用于非常小的程序。

要使用串行GC,请使用下面的JVM参数:

-XX:+UseSerialGC

并行垃圾回收

Simimar串行GC,它用于mark-copy年轻一代和mark-sweep-compact老一代。多个并发线程用于标记和复制/压缩阶段。您可以使用-XX:ParallelGCThreads=N选项配置线程数。

当您的主要目标是通过有效使用现有系统资源来提高吞吐量时,并行垃圾回收器适用于多核机器。使用这种方法,GC循环时间可以大大减少。

直到Java 8,我们已经看到并行GC作为默认垃圾回收器。从Java 9开始,G1是32位和64位服务器配置上的默认垃圾回收器。- JEP [248]

要使用并行GC,请使用下面的JVM参数:

-XX:+UseParallelGC

G1垃圾回收

G1(垃圾优先)垃圾回收器在Java 7中可用,旨在成为CMS回收器的长期替代品。G1回收器是一个并行的,并发的,逐步压缩的低暂停垃圾回收器。

这种方法涉及将内存堆分割成多个小区域(通常为2048)。每个地区都被标记为年轻一代(进一步分为伊甸园地区或幸存地区)或老一代。这样GC就可以避免一次回收整个堆,而是逐步处理问题。这意味着一次只考虑一小部分区域。

G1会跟踪每个区域包含的实时数据量。该信息用于确定包含垃圾最多的区域; 所以他们首先被回收。这就是为什么它是名称垃圾优先回收。

就像其他算法一样,不幸的是,压缩操作使用“ 停止世界”方法进行。但根据设计目标,您可以为其设定特定的性能目标。您可以配置暂停持续时间,例如在任何给定秒内不超过10毫秒。Garbage-First GC将尽最大努力以高概率实现这一目标(但不能确定,由于OS级别的线程管理,这很难实时)。

如果您想在Java 7或Java 8机器中使用,请使用JVM参数如下:

-XX:+UseG1GC

G1优化选项

描述

-XX:G1HeapRegionSize =16米

堆区的大小。该值将是2的幂,可以从1MB到32MB。目标是基于最小的Java堆大小,大约有2048个区域。

-XX:MaxGCPauseMillis = 200

为所需的最大暂停时间设置一个目标值。默认值是200毫秒。指定的值不适应您的堆大小。

-XX:G1ReservePercent = 5

这决定了堆中的最小预留量。

-XX:G1ConfidencePercent = 75

这是置信度系数暂停预测启发式。

-XX:GCPauseIntervalMillis = 200

这是每个MMU的暂停间隔时间片,以毫秒为单位。

GC自定义选项

GC配置标志

标识

描述

-Xms2048m -Xmx3g

设置初始和最大堆大小(年轻空间加上终身空间)。

-XX:+ DisableExplicitGC

这将导致JVM忽略应用程序的任何System.gc()方法调用。

-XX:+ UseGCOverheadLimit

这是用于限制在抛出OutOfMemory错误之前在垃圾回收中花费的时间的使用策略。

-XX:GCTimeLimit = 95

这限制了OutOfMemory抛出错误之前花在垃圾回收上的时间比例。这用于GCHeapFreeLimit。

-XX:GCHeapFreeLimit = 5

这会在引发OutOfMemory错误之前设置完整垃圾回收之后可用空间的最小百分比。这用于GCTimeLimit。

-XX:InitialHeapSize =3克

设置初始堆大小(年轻空间加上终身空间)。

-XX:MaxHeapSize =3克

设置最大堆大小(年轻空间加上终身空间)。

-XX:新尺寸=128米

设置年轻空间的初始大小。

-XX:MaxNewSize =128米

设置年轻空间的最大尺寸。

-XX:SurvivorRatio = 15

将单个生存者空间的大小设置为Eden空间大小的一部分。

-XX:PermSize =512米

设置永久空间的初始大小。

-XX:MaxPermSize参数=512米

设置永久空间的最大尺寸。

-Xss512k

以字节为单位设置专用于每个线程的堆栈区域的大小。

GC日志记录标志

标识

描述

-verbose:gc或-XX:+ PrintGC

这将打印基本垃圾回收信息。

-XX:+ PrintGCDetails

这将打印更详细的垃圾回收信息。

-XX:+ PrintGCTimeStamps

您可以为每个垃圾回收事件打印时间戳。秒是连续的并从JVM开始时间开始。

-XX:+ PrintGCDateStamps

您可以为每个垃圾回收事件打印日期戳。

-Xloggc:

使用这个你可以重定向垃圾回收输出到一个文件而不是控制台。

-XX:+打印\ TenuringDistribution

您可以在每个回收周期后打印有关年轻空间的详细信息。

-XX:+ PrintTLAB

您可以使用此标志打印TLAB分配统计信息。

-XX:+ PrintReferenceGC

使用此标志,您可以在停止世界暂停期间打印参考处理的时间(即弱,软等等)。

-XX:+ HEAPDUMP \ OnOutOfMemoryError

这会在内存不足的情况下创建堆转储文件。

总结

所以在这个java垃圾回收教程中,我们了解了以下内容 -

对象生命周期分为3个阶段,即对象创建,对象使用和对象破坏。

如何mark-sweep,mark-sweep-compact以及mark-copy机制炒菜锅。

不同的单线程和并发GC算法。

直到Java 8,并行GC是默认算法。

自java 9以来,G1已被设置为默认的GC算法。

此外,还有各种标志来控制垃圾回收算法的行为并记录任何应用程序的有用信息。

6种java垃圾回收算法_学习java垃圾回收相关推荐

  1. 学习java的心得体会_学习java的心得体会范文.doc

    学习java的心得体会范文 篇一:JAVA学习的心得体会 ? 国家队每一次踢球失败后都要说这么一句:我们回去后要好好总结,下次会打得更好! ? 总结不代表就能改过原有的不足,也不代表就能进步了 ? ( ...

  2. java 哈希算法_选择Java密码算法第1部分-哈希

    java 哈希算法 抽象 这是涵盖Java加密算法的三部分博客系列文章的第1部分. 该系列涵盖如何实现以下功能: 使用SHA–512散列 使用AES–256的单密钥对称加密 使用RSA–4096的公钥 ...

  3. java游戏猿人时代_学习java编程就业前景如何

    对于大多数学生来说,学习编程语言是为了更好的就业.由于Java在电子商务,企业级开发应用程序,游戏编程等许多领域中都发挥着重要作用,因此即使到2020年,学习Java仍将是一种热潮,其发展前景将非常可 ...

  4. java语言就业方向_学习java以后的就业方向有哪些-百度经验

    什么是java: Java是一种简单的,面向对象的,分布式的,说明型的,健壮安全的,结构中立的,可移植的,性能优异.多线程的动态语言.Java分为三个体系JavaSE(Java2 Platform S ...

  5. 学java的就业方向_学习Java的就业前景怎么样

    相信很多人对Java都有一定的了解,无论学习什么专业,最重要的一个目的就是进行就业,那么在选择专业的时候,应该如何选择呢?Java是现在很多人优先选择的专业,那么Java的就业前景如何呢?下面小编就几 ...

  6. java难不难学_学习Java难不难?如何学习?

    学习Java难不难?如何学习?很多人觉得学习java语言学习简单,而且直接,很适合初学编程的人,有句话说的好会者不难,难者不会,让初学者可以专注于做java编程,还不用困惑在晦涩难懂的语言上,那是天方 ...

  7. 学习java的中文网站_学习java的网站有哪些

    1.Stack overflow Stack可能是编程界中非常流行的网站了 , 是一个与程序相关的 IT 技术问答网站,用户可以在网站免费提交问题,浏览问题,索引相关内容,在创建主页的时候使用简单的 ...

  8. Java的泛型特性_学习Java的重中之重!

    Java的"泛型"特性,你以为自己会了 使用Java的小伙伴,对于Java的一些高级特性一定再熟悉不过了,例如集合.反射.泛型.注解等等,这些可以说我们在平时开发中是经常使用到的, ...

  9. 学java的正确方法_学习Java编程 这10个技巧不容错过--中享思途

    这是一个国外大神20多年的经验总结出来的-- "任何可能出错的事情,最后都会出错." 这就是人们为什么喜欢进行"防错性程序设计"的原因.偏执的习惯有时很有意义, ...

最新文章

  1. ReentrantLock+线程池+同步+线程锁
  2. 在panel中显示一个新的form
  3. RedMine 1.3.3 安装攻略
  4. Android -- Looper.prepare()和Looper.loop() —深度版
  5. 文献记录(part66)--一种基于交叉熵的社区发现算法
  6. delete不调用析构函数的两种情况
  7. Ubuntu 18.04.1 搭建Java环境和HelloWorld 1
  8. python清空列表的方法
  9. 注意力是非常宝贵的资源
  10. TCP/IP协议详解内容总结(怒喷一口老血)
  11. python snmp 自动化2-在python中使用snmp
  12. linux 如何避免进程killed_Linux 内核 / 进程管理 / 如何描述一个进程?
  13. Julia: Dates =DateFormat, format,parse.......
  14. VA番茄助手VisualAssist的神器工具教程
  15. jquery漂浮广告代码
  16. 碳足迹计算2021-02-06
  17. 55400-73-2,Ms-PEG5-Ms含有两个甲磺酸基部分的PEG连接物
  18. 程序人生-Hello‘sP2P
  19. Matlab/Simulink-PFC-Boost功率因数校正电路仿真搭建
  20. 五大定律助你公司走向成功-民兴商学院

热门文章

  1. CCF NOI1070 汉诺塔游戏
  2. UVA156 Ananagrams【map+vector】
  3. matplotlib tricks —— 平滑方法
  4. theano 编程技巧
  5. 二项分布的实现(np.random.binomial)
  6. mysql读写分离java配置方法_springboot配置数据库读写分离
  7. JAVA控制台扑克牌游戏,洗牌,发牌,比较大小
  8. python3入门经典100例-Python3经典100例(Python3入门习题) 含答案 doc版
  9. python3入门代码-Python3入门(三)——Python基础语法
  10. python是什么-马哥教育官网-专业Linux培训班,Python培训机构