首页 > 其他分享 >对象存在位置

对象存在位置

时间:2024-07-17 15:09:16浏览次数:7  
标签:存在 Eden Survivor 对象 位置 GC JVM Minor

对象优先在 Eden 分配

  • 堆分为新生代和老年代,新生代用于存放使用后就要被回收的对象(朝生夕死),老年代用于存放生命周期比较长的对象。

  • 创建的大部分对象,都属于生命周期较短的对象,所以会存放在新生代。新生代又细分 Eden、From Survivor、To Survivor,对象会优先在 Eden 区分配。

  • 随着对象的不断创建,Eden 剩余地内存空间就会越来越少,随后就会触发 Minor GC,于是 JVM 会把 Eden 区存活的对象转入 From Survivor 空间。

  • Minor GC 后,又创建的新对象会继续往 Eden 区分配。

  • 于是,随着新对象的创建,Eden 的剩余内存空间就会越来越少,又会触发 Minor GC,此时,JVM 会对 Eden 区和 From Survivor 区中的对象进行存活判断,对于存活的对象,会转移到 To Survivor 区。

  • 下一次 Minor GC,存活的对象又会从 To 到 From,这样就总有一个 Survivor 区是空的,而另外一个是无碎片的。

大对象直接进入老年代

  • 对于上面的流程,也有例外的存在,如果一个对象很大,一直在 Survivor 空间复制来复制去,就会很浪费性能,所以这些大对象会直接进入老年代。这种策略的目的是减少垃圾回收时的复制开销。

  • 可以通过 -XX:PretenureSizeThreshold 参数设置直接分配大对象到老年代的阈值。如果对象的大小超过这个阈值,它将直接在老年代中分配。例如,如果想将阈值设置为 1MB(1024KB),可以这样设置:
-XX:PretenureSizeThreshold=1048576

长期存活的对象将进入老年代

  • 对象在每次从一个 Survivor 区转移到另外一个 Survivor 区时,它的年龄就会增加。当对象的年龄达到一定阈值(默认为 15),则它会被转移到老年代。可以用 -XX:PretenureSizeThreshold=10 来设置年龄。

  • 虚拟机为了给对象计算他到底经历了几次 Minor GC,会给每个对象定义了一个对象年龄计数器。如果对象在 Eden 中经过第一次 Minor GC 后仍然存活,移动到 Survivor 空间年龄加 1,在 Survivor 区中每经历过 Minor GC 后仍然存活年龄再加 1。年龄到了 15,就到了老年代。

动态年龄判断

  • 除了年龄达到 MaxTenuringThreshold,还有另外一个方式进入老年代,那就是动态年龄判断:JVM 会检查每个年龄段的对象大小,并估算它们在 Survivor 空间中所占的总体积。JVM 会选择一个最小的年龄,使得该年龄及以上的对象可以填满 Survivor 空间的一部分(通常小于总空间的一半),然后将这些对象晋升到老年代。

  • 比如 Survivor 是 100M,Hello1 和 Hello2 都是 3 岁,且总和超过了 50M,Hello3 是 4 岁,这个时候,这三个对象都将到老年代。

空间分配担保

  • 存活的对象会放入另外一个 Survivor 空间,如果这些存活的对象比 Survivor 空间还大呢

整个流程如下:

  • Minor GC 之前,JVM 会先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果大于,则发起 Minor GC。
  • 如果小于,则看 HandlePromotionFailure 有没有设置,如果没有设置,就发起 Full GC。
  • 如果设置了 HandlePromotionFailure,则看老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果小于,就发起 Full GC。
  • 如果大于,发起 Minor GC。Minor GC 后,看 Survivor 空间是否足够存放存活对象,如果不够,就放入老年代,如果够放,就直接存放 Survivor 空间。如果老年代都不够放存活对象,担保失败(Handle Promotion Failure),发起 Full GC。

HandlePromotionFailure 的作用,当设置为 true 时(默认值),JVM 会尝试继续 Minor GC,即使老年代空间不足以容纳所有需要晋升的对象。JVM 会尝试清理更多的老年代空间或者采用其他措施来应对空间不足的情况。避免因为老年代空间不足而过早触发 Full GC(全堆回收)。Full GC 通常比 Minor GC 更耗时,会导致更长时间的停顿。

栈和方法区

  • Java 创建的对象几乎都在堆中,这包括通过 new 关键字创建的对象和数组。而对象的引用,通常存放在栈中,比如说当你在方法中声明一个变量 MyClass obj = new MyClass(); 时,变量 obj(一个指向堆中对象的引用)存储在栈上。

  • 方法区用于存储已被 JVM 加载的类信息、常量、静态变量以及即时编译器编译后的代码。Java 8 中,永久代被元空间(Metaspace)所取代。元空间使用本地内存(操作系统的内存),而非 JVM 内存。

标签:存在,Eden,Survivor,对象,位置,GC,JVM,Minor
From: https://www.cnblogs.com/sprinining/p/18307426

相关文章

  • c++初阶知识——类和对象(中)
    目录1.类的默认成员函数2.构造函数 3.析构函数 4.拷贝构造函数5.运算符重载 5.1赋值运算符重载 5.2使用运算符重载等特性实现日期类 6.取地址运算符重载6.1 const成员函数 6.2取地址运算符重载1.类的默认成员函数    默认成员函数就是⽤⼾没有......
  • c++初阶知识——类和对象(下)
    目录1.构造函数深入2.类型转换3.static成员 4.友元5.内部类6.匿名对象 7.对象拷⻉时的编译器优化1.构造函数深入(1)前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是......
  • 《JavaSE》---12.<面向对象系列之(继承)>
    目录系列文章目录前言一、继承是什么?1.1继承的概念1.2继承的语法1.3父类子类的别名1.4继承的作用1.4继承的代码实践代码示例:输出结果:小结:二、继承中访问成员变量与方法(this与super的用法)2.1当父类成员变量、方法与子类成员变量、方法名字不同时2.2当父类成员变量......
  • 特例模式与空对象模式
    特例模式指的是为处理某些特殊情况而创建的特殊类或对象。这些类或对象专门用于处理特定的异常情况或边界条件,以便简化主业务逻辑的处理。应用场景:用于需要处理某些特殊输入、边界条件或错误情况的场景。例如,处理数据库查询时,返回一个特例对象表示没有找到数据。空对象模式通过......
  • 不存在的misc密码
    工具CyberChef千千秀字随波逐流工作室CTF在线工具Bugkubase家族base16666C61677B3132333435363738397Dbase32MZWGCZ33GEZDGNBVGY3TQOL5base45U.C5EC$PFQF60R6J%6%47Z2base583sCWBxPYGkdVfKBgHsruabase62ko4RLHSQGg5zPcaYwLozbase64ZmxhZ3sxMjM0NTY3ODl9b......
  • C++ 多态:探索对象的动态行为
    C++多态:探索对象的动态行为在C++中,多态性是一种强大的特性,它允许我们通过基类指针或引用来调用派生类的方法。多态性不仅增加了程序的灵活性,还使得代码更加易于扩展和维护。本文将深入探讨C++中的多态性,包括静态多态(主要通过函数重载和模板实现)和动态多态(主要通过虚函数......
  • Python进阶(1)--面向对象
    文章目录面向对象类的定义类的构造实例化一个类三大特点封装私有属性继承和多态继承继承的作用多态总结总结面向对象Python是一种广泛使用的解释型、高级编程、通用型编程语言,它以其简洁、易读以及面向对象的特性而闻名。面向对象编程(Object-OrientedProgramm......
  • BeautifulSoup模块之初识,BeautifulSoup模块之四种对象,BeautifulSoup模块之文档树操
    ⅠBeautifulSoup模块之初识【一】介绍【1】简言简单来说,BeautifulSoup是python的一个库最主要的功能是从网页抓取数据。【2】官方解释BeautifulSoup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要......
  • 十天学会Python——第6天:面向对象
    1面向对象1.1类和对象(用类创建对象)类的语法:class类名():执行的代码对象的语法:对象名=类名()classWasher(): #定义类defwash(self): print("可以洗衣服")print(self) #返回结果是跟下面gree的地址一样gree1=Washer()......
  • 向url中的添加参数,要求传递对象后解析成参数到url上
    例如:传参{name:'张三',age:18},functionurlFn(obj){ leturl='http://www.alibb.com' letkeys=Object.keys(obj) letvalues=Object.values(obj) url+='?' for(leti=0;i<keys.length;i++){ if(i==keys.length-......