jvm基础知识五----分代垃圾回收详细

zz/2024/7/13 12:16:16

为什么要分代

 

分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期

的对象可以采取不同的收集方式,以便提高回收效率。

 

在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如Http请求中的

 

Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些

对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:String对象,由于其

不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。

 

试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,花费时间相对会
长,同时,因为每次回收都需要遍历所有存活对象,但实际上,对于生命周期长的对象而言,这种遍历是没有
效果的,因为可能进行了很多次遍历,但是他们依旧存在。因此,分代垃圾回收采用分治的思想,进行代的划

 

分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

 

如何分代

 

   ff

如图所示:
虚拟机中的共划分为三个代:年轻代(Young Generation)、年老点(Old Generation)和持久代
(Permanent Generation)。
其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象

关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。


年轻代:


所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当

Eden区满时,存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此

区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个

Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。

需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时
存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去
过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于
两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。

 

年老代:


在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的
都是一些生命周期较长的对象。


持久代:


用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或
者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新
增的类。持久代大小通过-XX:MaxPermSize=<N>进行设置。


什么情况下触发垃圾回收
由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。


Scavenge GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,
清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对
年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很
大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲
出来。


Full GC
对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比Scavenge
GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调
节。有如下原因可能导致Full GC:
· 年老代(Tenured)被写满
· 持久代(Perm)被写满
· System.gc()被显示调用

·上一次GC之后Heap的各域分配策略动态变化

 

 

 


http://www.ngui.cc/zz/2762660.html

相关文章

如何在ubuntu下设置永久的alias别名

永久的alias别名步骤如下&#xff1a; 第一步&#xff1a; cd /home/用户名 切换超级用户 sudo -s 第二步&#xff1a; 编辑 vim ./.bashrc 第三步&#xff1a; 在下图横线处输入别名 第四歩&#xff1a;保存退出 第五步&#xff1a;执行命令 source ./.bas…

nginx负载均衡配置---nginx的学习之路

Nginx 负载均衡 1. Nginx 负载均衡基础知识 nginx 的 upstream 目前支持 4 种方式的分配 1)、轮询&#xff08;默认&#xff09; 每个请求按时间顺序逐一分配到不同的后端服务器&#xff0c;如果后端服务器 down 掉&#xff0c;能自动剔除。 2)、weight 指定轮询几率&#xf…

配置Nginx来支持PHP----重点介绍Nginx如何通过PHP_FPM的FastCGI进程对PHP进行解析处理。

Nginx的安装特别简单&#xff0c;前面已经对此进行了详细介绍&#xff0c;这里不再进行讲述。下面重点介绍Nginx如何通过PHP_FPM的FastCGI进程对PHP进行解析处理。 由于Nginx本身不会对PHP进行解析&#xff0c;因此要实现Nginx对PHP的支持&#xff0c;将对PHP页面的请求交给Fas…

nginx响应与处理请求的方法详解

本文详细了nginx服务器响应与处理http等请求的方法&#xff0c;并讲解了nginx虚拟主机的配置方法&#xff0c;有需要的朋友参考下吧。 一&#xff0c;nginx基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求。 从一个简单的配置&#xff08;其中全部3个虚拟主机都在…

每天一个linux命令(9):cd命令

Linux cd 命令可以说是Linux中最基本的命令语句&#xff0c;其他的命令语句要进行操作&#xff0c;都是建立在使用 cd 命令上的。 所以&#xff0c;学习Linux 常用命令&#xff0c;首先就要学好 cd 命令的使用方法技巧。 1. 命令格式&#xff1a; cd [目录名] 2. 命令功能&am…

Log4j实用手册

Log4j实用手册 简介 1.Log4J是Apache的一个开源项目,是用来操作程序日志信息的框架。 ______________________________________________________________________________________ 2.Log4J的功能通过配置log4j.properties属性文件实现。 _________________________________…

修改linux用户密码(passwd)

对于初学者来说,如何修改linux用户密码也不是件容易的事,其实非常简单,下面举例说明: &#xff08;1&#xff09;修改root用户密码 如果是以root身份登录,修改root密码. 只要输入 passwd 就会出现: New password: Retype new password: 按提示输入密码确认即可. &#xf…

centos7 strace的安装

strace是一个功能强大的调试,分析诊断工具&#xff0c;主要用来监视系统调用。 1.下载strace-xxx.tar.xz 下载网址是&#xff1a;http://sourceforge.net/project/showfiles.php?group_id2861&package_id2819&#xff1b; 2.解压 $ xz -d ***.tar.xz $ tar -xvf *…

Android Fragment生命周期和用法解析

Fragment生命周期图&#xff1a; Fragment与Activity生命周期对比图&#xff1a; 2 生命周期分析 1. 当一个fragment被创建的时候&#xff0c;它会经历以下状态. onAttach()onCreate()onCreateView()onActivityCreated() 2. 当这个fragment对用户可见的时候&#xff0c;它会…