简单谈谈JVM中的GC(上)

上图就是JVM的分代模型,JVM根据Object的生命周期长短,将其分为上述的三个层次(也称代)。不同的层次,其GC(收集回收)算法不一样

  • Young Generation(年轻代、young代)

对象的初次创建就会在young代,大部分对象在创建后不再被使用,于是就会被年轻代的GC机制清理掉,这个GC叫做Minor GC或Young GC(注意:1、这是一个停顿动作;2、这并不表示年轻代内存不足,仅表示Eden区满了,发生GC)。

年轻代包括:Eden区+两个存活区(S0和S1,即上图中from和to)。young gc机制如下图:

  1. 大部分对象在创建完后就会被分配在Eden区,使用完被销毁
  2. 当Eden区满的时候,执行Minor GC,将可销毁的对象清除掉,将剩余不可销毁的对象迁移到存活区S0
  3. 每次Eden发生Minor GC时,剩余存活对象都会到S0区(此时S1区空白)
  4. 当S0区满的时候,会将其中仍然存活的对象复制到S1,同时Eden发生Minor GC时,剩余对象都会到S1区(此时S0区空白)
  5. S0和S1会来回复制存放(总有一个是空白),但某对象来回存放次数超过15次(-XX:MaxTenuringThreshold设置的值,默认是15),则不再存在young代,将被存放到old代
  6. 当Minor GC时,存活的对象大过S0区的大小,则会直接进入old代

总结下:

Eden区是一个连续的空间,并且S区总有一个空白的。经过一次GC和复制后,一个S区保留存活对象,而Eden区和另一个S区可直接清空,到下一次GC时,两个S区的角色互换。这就是著名的“停止-复制(Stop-and-copy)”清理法。

  • Old Generation(年老代、old代)

对象如果在young存活了足够长的时间(多次Minor GC,仍未能销毁),则会被复制到old代,old代的空间一般比young代大,能够存放更多的对象,一般来说old代上GC次数也比young代少。当old年代空间不足时,将执行Major GC,也叫Full GC。

old代的对象销毁并非跟young代一样,而是通过标记-整理算法,即:标记出仍然存活的对象(存在引用的),将所有存活的对象向一端移动,以保证内存的连续。

但当young代进入old代时,如果进入old代的对象大小大于old代剩余空间大小,则会直接触发一次Full GC(可通过-XX:+HandlePromotionFailure额外设置)

题外话:可能存在old代的对象引用young代对象的情况,old代会维护一个512 byte的块“card table”,里面保存old代的对象引用young代对象的记录,当young gc时,只需查这里,不用遍历整个old代对象

  • Permanent Generation(持久代)

    主要存放代码(字节码),字符串常量池,静态变量,可持久化的数据等;

每次Full GC时,同时也会销毁掉持久代中可销毁的对象

什么是可销毁的对象?

所有的Java对象构成一颗近似“搜索树”的结构,有一个root根节点,每次从root出发向下搜索,当整个树遍历完成后,那些不在其中的变量则视为"垃圾"。

如上图所示,红色部分对象均属于可删除对象

什么是java的root节点?

所有正在运行的线程的栈上的引用变量。所有的全局变量。所有ClassLoader

知乎回答: https://www.zhihu.com/question/50381439

接下来总结的是:GC算法和部分JVM参数讲解

时间: 2024-10-21 17:21:06

简单谈谈JVM中的GC(上)的相关文章

简单谈谈JVM中的GC(中)

书接上文,在了解JVM的分代模型后,接着来简单聊聊JVM中GC算法和不同的GC收集器[求关注] GC回收算法 一个GC回收算法通常会做这么几件事: 1.遍历内存,找到被引用的对象 2.清理掉这些未被标记对象的内存 3.被清理掉的内存放回内存中,供其他地方使用 上文也提及过,目前JVM中的搜索引用对象是用的根搜索方式,再重复引用下: 所有的Java对象构成一颗近似"搜索树"的结构,有一个root根节点,每次从root出发向下搜索,当整个树遍历完成后,那些不在其中的变量则视为"垃

简单谈谈JVM中的GC(下)

在系列的最后,简单谈谈一些会有坑的JVM参数配置,以避免大家再多次踩坑 -XX:+DisableExplicitGC 很多的JVM标准配置中都有该选项,那么它究竟是干嘛的? 它会让System.gc()变成一次空调用,并不会真的发生一次Full Gc.除此以外,它还能避免第三方库定时引发的Full Gc(没错,说的就是RMI机制),看来很美好,对不对? 但有一种情况:应用本身GC正常,很久都不会Full Gc,但堆外内存增长很快,并且JVM启用了-XX:+DisableExplicitGC.你就

浅析JVM中的GC日志

目录 一.GC日志的格式分析 二.运行时开启GC日志 一.GC日志的格式分析 在讲述GC日志之前,我们先来运行下面这段代码 1 package com.example; 2 3 public class TestMinorGC { 4 private static final int _1MB = 1024*1024; 5 6 public static void testAllocation() { 7 byte[] allocation1, allocation2, allocation3,

简单谈谈js中的MVC

MVC是什么? MVC是一种架构模式,它将应用抽象为3个部分:模型(数据).视图.控制器(分发器). 本文将用一个经典的例子todoList来展开(代码在最后). 一个事件发生的过程(通信单向流动): 1.用户在视图 V 上与应用程序交互 2.控制器 C 触发相应的事件,要求模型 M 改变状态(读写数据) 3.模型 M 将数据发送到视图 V ,更新数据,展现给用户 在js的传统开发模式中,大多基于事件驱动的: 1.hash驱动 2.DOM事件,用来驱动视图 3.模型事件(业务模型事件和数据模型事

jvm中的年轻代 老年代 持久代 gc

虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent Generation).其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大.年轻代和年老代的划分是对垃圾收集影响比较大的. 年轻代: 所有新生成的对象首先都是放在年轻代的.年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象.年轻代分三个区.一个Eden区,两个Survivor区(一般而言).大部分对象在Eden区中生成.当Ed

jvm系列:Java GC 分析

Java GC就是JVM记录仪,书画了JVM各个分区的表演. 什么是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢.这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制.概括地说,该机制对JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存需要回收,根据一定

JVM学习之GC常用算法

出处:博客园左潇龙的技术博客--http://www.cnblogs.com/zuoxiaolong,多谢分享 GC策略解决了哪些问题? 既然是要进行自动GC,那必然会有相应的策略,而这些策略解决了哪些问题呢,粗略的来说,主要有以下几点. 1.哪些对象可以被回收. 2.何时回收这些对象. 3.采用什么样的方式回收. GC策略采用的何种算法 有关上面所提到的三个问题,其实最主要的一个问题就是第一个,也就是哪些对象才是可以回收的,有一种比较简单直观的办法,它的效率较高,被称作引用计数算法,其原理是:

JVM——成为Java GC专家(1)

原文: Understanding Java Garbage Collection JVM--成为Java GC专家(1) 理解Java垃圾回收机制(GarbageCollection,简称GC)是如何工作的有什么好处?做为一名软件工程师,为了满足自己的好奇心去了解他是其中的一个原因,并且理解GC工作原理更能让我们写出性能更好.更健壮的Java应用程序. 这仅仅是我个人观念,但是我相信.精通GC是做为一个优秀的Java工程师的必要条件.如果你对GC工作原理感兴趣.那么就意味着你已经具有了开发一定

JVM中的G1垃圾回收器

我们先回顾一下主流Java的垃圾回收器(HotSpot JVM).本文是针对堆的垃圾回收展开讨论的. 堆被分解为较小的三个部分.具体分为:新生代.老年代.持久代. 绝大部分新生成的对象都放在Eden区,当Eden区将满,JVM会因申请不到内存,而触发Young GC ,进行Eden区+有对象的Survivor区(设为S0区)垃圾回收,把存活的对象用复制算法拷贝到一个空的Survivor(S1)中,此时Eden区被清空,另外一个Survivor S0也为空.下次触发Young GC回收Eden+S