会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 Java中GC原理及GC日志剖析!

Java中GC原理及GC日志剖析

时间:2025-11-05 15:50:58 来源:益强数据堂 作者:应用开发 阅读:611次

 一.概述

学习Java的理及我们都知道垃圾收集(GC),大部分人把这项技术当作是日志Java语言的伴生产物。事实上,剖析GC的理及历史比Java久远,1960年诞生于MIT的日志Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言。那我们今天就研究下垃圾收集原理。剖析

二.对象已死吗?理及

Java的垃圾回收主要是对堆内存的回收,里面存放着Java几乎所有的日志对象实例,垃圾回收之前是剖析要确定哪些还“存活”,哪些已经“死去”。理及

1.引用计数器法

给对象添加一个引用计数器,日志每当有地方对他进行引用时计数器值➕1;当引用失效时,剖析计数器值就➖1,理及任何时候计数器值为0的日志时候表示对象不可能在使用的。

2.可达性分析算法

通过一系列称为“GC Roots”的剖析对象作为起点,从这些节点往下搜索,搜索所走过的路径称为“引用链”,当一个对象到“GC Roots”没有任何引用链相连时,高防服务器则证明对象是不可用的。

代码示例:

GC日志如下:

我们很明显的看到GC日志中6092K->456K,意味着虚拟机并没有因为这两个对象互相引用而不回收他们,所以Java虚拟机使用的是可达性分析算法标记的。

其实即使被可达性分析算法标记的不可达对象也不是一定会被回收的,虚拟机会对这些对象进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()已经被虚拟机调用过,虚拟机将这两种情况视为“没有必要执行”。如果对象被判定有必要执行,finalize()方法是并在finalize()中与“GC Roots”建立关联,则此对象不会被回收了。

三.垃圾回收算法

我们知道了虚拟机怎么标记一个对象是否可用,那他怎么进行回收的呢?其实堆内存可以分为新生代和老年代,新生代又被划分为一个Eden和两个Survivor区域,他们的比例为8:1:1,不同的云服务器提供商垃圾收集器厂商对这两个区域给出了不同的算法。

1.新生代——复制算法

新生代对象的特点就是,大部分对象在一次GC中会被回收掉,所以使用的是复制算法:新生代每次创建对象的时候只会使用一个Eden和其中的一块Survivor,在垃圾回收时将存活的对象复制到另外一块Survivor区域,最后清理掉Eden和刚才的Survivor区域。

2.老年代——标记-整理算法

老年代一般保存的是一些大对象,或者不被经常回收的对象,根据特点使用的标记-整理算法:如同名字一样,算法分为“标记”和“整理”两个阶段:首先先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象进行整理,将被标记的对象都向一端移动,然后直接清理掉边界以外的内存。

四.HotSpot算法实现

上面说了我们怎么标记对象“死亡”和怎么进行垃圾回收的,但在HotSpot虚拟机在实现这些算法上是b2b信息网必须对算法的执行效率进行考量的。

1.安全点

在可达性分析中对执行的时间的敏感体现在GC停顿上,其意思是在整个分析的过程中看起来就像被冻结在某一个时间点上的,不可以出现分析的过程中引用关系在不断变化,如果这点得不到保证则分析的结果的准确性就得不到保障。这点是导致在GC进行时需要停顿所有的Java执行线程。

当执行系统停顿下来后,虚拟机并不需要全部上下文和全局所有的位置,虚拟机通过一个OopMap的数据结构在类加载的时候将对象的偏移量数据信息记录下来,所以GC扫描是直接得到这些信息的。其实这些通过指令被加入进行记载对象信息的OopMap位置也叫做安全点,程序执行时并非所有点都可以停下来开始GC的,只有在到达安全点才能停顿。安全点机制程序执行中,在不太长的时间内会遇到可进入GC的安全点。在实际中会遇到在GC时有线程不再执行,例如线程被挂起了。这是我们需要安全区域去解决。

2.安全区域

安全区域是指在一段代码片段中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的。在代码执行到安全区域时,首先表示这直接进去安全区域,这样虚拟机在这段时间GC时就不用管那些标记为安全区域的线程了。当离开安全区域时首先得判断GC分析是否完成,没完成则需要等待。

五.理解GC日志

这是上图打印的GC日志

[GC (System.gc()) [PSYoungGen: 6092K->448K(38400K)] 6092K->456K(125952K), 0.0051702 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]

其中,PSYoungGen表示的是新生代GC不同垃圾收集器新生代名称不一样,6092K->448K(38400K)表示新生代大小的变化,6092K->456K(125952K)表示堆内存的大小变化,后面表示用时。

[Full GC (System.gc()) [PSYoungGen: 448K->0K(38400K)] [ParOldGen: 8K->378K(87552K)] 456K->378K(125952K), [Metaspace: 3050K->3050K(1056768K)], 0.0056045 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

这里表示发生在老年代的GC(Major GC/Full GC) 它只是为伴随一次的新生代的GC(Minor GC),448K->0K(38400K)表示新生代内存变化,8K->378K(87552K) 表示老年代GC变化,456K->378K(125952K)表示GC前后堆内存的变化。

【本文是专栏机构“AiChinaTech”的原创文章,微信公众号( id: tech-AI)”】

戳这里,看该作者更多好文

(责任编辑:应用开发)

上一篇:单反相机录像的优劣势及应用(深入了解单反相机录像功能的特点和适用场景)
下一篇:假如你是一个测试入侵侦测系统或一些网络访问控制策略的网络管理员,那么你经常需要抓取数据包并在离线状态下分析这些文件。当需要保存捕获的数据包时,我们一般会存储为 libpcap 的数据包格式 pcap,这是一种被许多开源的嗅探工具以及捕包程序广泛使用的格式。假如 pcap 文件被用于入侵测试或离线分析的话,那么在将他们注入网络之前通常要先对 pcap 文件进行一些操作。在该文中,我将介绍一些操作 pcap 文件的工具,以及如何使用它们 。Editcap 与 MergecapWireshark,是最受欢迎的 GUI 嗅探工具,实际上它带了一套非常有用的命令行工具集。其中包括 editcap 与 mergecap。editcap 是一个万能的 pcap 编辑器,它可以过滤并且能以多种方式来分割 pcap 文件。mergecap 可以将多个 pcap 文件合并为一个。 该文就是基于这些 Wireshark 命令行工具的。假如你已经安装过 Wireshark 了,那么这些工具已经在你的系统中了。假如还没装的话,那么我们接下来就安装 Wireshark 命令行工具。 需要注意的是,在基于 Debian 的发行版上我们可以不用安装 Wireshark GUI 而仅安装命令行工具,但是在 Red Hat 及 基于它的发行版中则需要安装整个 Wireshark 包。Debian, Ubuntu 或 Linux Mint复制代码代码如下:$ sudo apt-get install wireshark-commonFedora, CentOS 或 RHEL复制代码代码如下:$ sudo yum install wireshark当安装好工具后, 就可以开始使用 editca 与 mergecap 了。pcap 文件过滤通过 editcap, 我们能以很多不同的规则来过滤 pcap 文件中的内容,并且将过滤结果保存到新文件中。首先,以“起止时间”来过滤 pcap 文件。 - A < start-time >和 - B < end-time >选项可以过滤出在这个时间段到达的数据包(如,从 2:30 ~ 2:35)。时间的格式为 “ YYYY-MM-DD HH:MM:SS。复制代码代码如下:$ editcap -A 2014-12-10 10:11:01 -B 2014-12-10 10:21:01 input.pcap output.pcap 也可以从某个文件中提取指定的 N 个包。下面的命令行从 input.pcap 文件中提取100个包(从 401 到 500)并将它们保存到 output.pcap 中:复制代码代码如下:$ editcap input.pcap output.pcap 401-500使用 -D < dup-window > (dup-window可以看成是对比的窗口大小,仅与此范围内的包进行对比)选项可以提取出重复包。每个包都依次与它之前的 < dup-window >-1 个包对比长度与MD5值,假如有匹配的则丢弃。复制代码代码如下:$ editcap -D 10 input.pcap output.pcap 遍历了 37568 个包, 在 10 窗口内重复的包仅有一个,并丢弃。也可以将 < dup-window >定义成时间间隔。使用-w < dup-time-window >选项,对比< dup-time-window >时间内到达的包。复制代码代码如下:$ editcap -w 0.5 input.pcap output.pcap 检索了 50000 个包, 以0.5s作为重复窗口,未找到重复包。分割 pcap 文件当需要将一个大的 pcap 文件分割成多个小文件时,editcap 也能起很大的作用。将一个 pcap 文件分割成数据包数目相同的多个文件复制代码代码如下:$ editcap -c 输出的每个文件有相同的包数量,以 < output-prefix >-NNNN的形式命名。以时间间隔分割 pcap 文件复制代码代码如下: $ editcap -i 合并 pcap 文件假如想要将多个文件合并成一个,用 mergecap 就很方便。当合并多个文件时,mergecap 默认将内部的数据包以时间先后来排序。复制代码代码如下:$ mergecap -w output.pcap input.pcap input2.pcap [input3.pcap . . .]假如要忽略时间戳,仅仅想以命令行中的顺序来合并文件,那么使用 -a 选项即可。例如,下列命令会将 input.pcap 文件的内容写入到 output.pcap, 并且将 input2.pcap 的内容追加在后面。复制代码代码如下:$ mergecap -a -w output.pcap input.pcap input2.pcap 总结在这篇指导中,我演示了多个 editcap、 mergecap 操作 pcap 文件的例子。除此之外,还有其它的相关工具,如 reordercap用于将数据包重新排序,text2pcap 用于将 pcap 文件转换为文本格式, pcap-diff用于比较 pcap 文
推荐内容
  • 富勒G900如何让你体验卓越品质?(全面解析富勒G900的性能与功能,为你提供最佳游戏体验!)
  • U11系统(探索U11系统的功能和特点)
  • 高通骁龙805的发热问题及解决方法(骁龙805发热原因分析及降温技巧)
  • 华硕装机教程完整版
  • 解决联想电脑网络请求错误的方法
  • 小狗除螨仪(便携实用|安全无刺激|舒适体验)