jvm垃圾收集器与内存分配策略

JVM--垃圾收集器与内存分配策略 1.概述 垃圾回收器的历史比Java久远,诞生于Lisp(第一门开始使用内存动态分配和垃圾收集技术的语言). 2.对象已死? 1.引用计数法 概述:在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能在被使用的. 但主流Java虚拟机并没有采用:当单纯的引用计数就很难解决对象之间的相互循环引用的问题. 2.可达性分析算法 概述:通过一系列称为"GC Roots"的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索, 阅读详情

                                                               jvm垃圾收集器与内存分配策略

垃圾收集器与内存分配策略:

  • 以下参考周志明的<<深入理解jvm高级特性与最佳实践>>。

判断对象是否存活:

  • 引用计数:通过判断对象被引用的次数(为0,则表示不可被使用),但这很难解决对象相互循环引用的问题。
  • 根搜索算法:即采用有向图的方式,判断从GC Roots到某个对象是否可达。

       jvm垃圾收集器与内存分配策略

上图中obj1,obj2,obj3,obj4可达,obj5,obj6不可达(可被GC回收)。

  • 可作为GC Roots的对象:

       1. 虚拟机栈中局部变量引用的对象。

       2. 类静态属性引用的对象。

       3. 常量引用的对象。

       4. JNI中引用的对象。

java中的引用类型:

java中有四种引用类型(由强到弱):

  • 强引用(StrongReference): 只要对象有被强引用,对象就不会被GC回收,如Object o = new Object()中的o就是强引用。
  • 软引用(SoftReference): 软引用的对象为不必须回收的对象,但在内存不足发生溢出之前,GC会在回收时,将软引用的对象视作可可回收的对象,所以SoftReference可以用来做一些高速缓存。
  • 弱引用(WeakReference):软引用的对象只能存活到下一次GC的时候,无论内存是否足够,如WeakHashMap类。
  • 虚引用(PhantomReference): 虚引用对对象存活无影响,唯一的用处,可以与ReferenceQueue结合使用,在对象被回收时,得以通知。

方法区(Permanent Generation)回收:

  • java8中已经移除了Permanent Generation, 取而代之的是MetaSpace区。
  • 方法区回收的对象:

       1. 废弃常量(如无引用的常量字符串)。

       2. 无用的类。

  • 类什么条件下可以被回收:

       1. 该类的所有实例已经被回收。

       2. 加载该类的ClassLoader已经被回收。

       3. 该类的java.lang.Class对象没有被引用,无法任何地方通过反射访问该类。

垃圾回收算法:

  • 标记-清除(Mark-Sweep): 先标记要回收的对象,再统一进行回收操作。

       简单方便,内存碎片化严重

  • 复制算法: 将堆分为2份,1份空白(A),1份存放对象(B),GC后,将B中存活对象复制到A中,然后将B变成空白。

       无内存碎片化, 浪费可用内存

  • 标记-整理(Mark-Compact): 先标记可回收对象,将存活对象都移向一端,再回收对象。

      无内存碎片化,充分利用可用内存

  • 分代回收:将堆分为年轻代和老年代,年轻代(存活对象少)采用复制算法,老年代(对象存活长)可采用标记-清除或标记-整理。

       根据对象存活特性,合理使用不同回收算法,商业JVM都使用该回收算法。

垃圾收集器:

  • 既然jvm采用分代回收,那么年轻代和老年代各自使用的垃圾收集器也不一样。
  • 年轻代使用的垃圾收集器:Serial,ParNew,Parallel Scavenge。
  • 老年代使用的垃圾收集器:CMS, Serial Old(MSC), Parallel Old。
  • 通用的垃圾收集器:G1。

Serial/Serial Old收集器:

  • 单线程回收,回收期间暂停其他所有工作线程。(jvm -client模式下年轻代默认的收集器)

ParNew收集器:

  • 多线程同时回收,回收期间暂停其他所有工作线程。

Parallel Scavenge收集器:

  • 和ParNew类似,但其重在控制cpu吞吐量大小。

Serial Old收集器:

  • Serial老年代版本。使用单线程,标记-整理的算法。

Parallel Old收集器:

  • Parallel Scavenge收集器的老年代版本。使用多线程,标记-整理算法。

CMS(Concurrent Mark Sweep)收集器:

  • 以获得最短回收暂停时间为目标。这是一款真正意义的并发收集器(可允许垃圾收集线程与用户线程并行)。其主要有四个阶段:

       1. 初始标记:标记GC Roots可关联的对象,会暂停用户线程。

       2. 并发标记:GC Roots Tracing过程,用户线程并行。

       3. 重新标记:重新标记由于在并发标记过程中用户线程导致的对象状态变化,会暂停用户线程。

       4. 并发清理:清理可回收对象,用户线程并行。

G1(Garbage First)收集器:

  • 一款先进的垃圾收集器。它针对整个堆,将其分为大小相等的区域,记录每个区占用信息,优先回收回收价值更高的区域。
  • 详解介绍:http://my.oschina.net/indestiny/blog/214160

这些收集器都一些可控参数,根据实际场景来调整,这里是官方文档:

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

内存分配与回收策略:

  • jvm内存分配基本就是堆上分配,也有可能栈上(如通过逃逸分析,可以在栈上分配)。
  • 看看整个堆分区:

jvm垃圾收集器与内存分配策略

对象优先分配在Eden区:

内存分配回收实例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 内存分配回收
  * -XX:+PrintGCDetails 打印GC信息
  * -Xms12M 起始堆大小
  * -Xmx12M 最大堆大小
  * -Xmn6M 年轻代大小
  * -XX:SurvivorRatio=6 Eden:S0:S1 = 4:1:1
  *
  * jvm args:
  * -XX:+PrintGCDetails -Xms12M -Xmx12M -Xmn6M -XX:SurvivorRatio=4
  */
public class MemoryAllocate {
     private static final int _1M =  1024 * 1024 ;
     
     public static void main(String[] args) {
         byte [] b1 =  new byte [_1M];  // allocate 1M
         byte [] b2 =  new byte [_1M* 2 ];  // allocate 2M
         byte [] b3 =  new byte [_1M];  // allocate 1M, 发生年轻代GC(Minor GC)
     }
}
gc信息如下:

jvm垃圾收集器与内存分配策略

  • 垃圾回收方式:

      1.Minor GC:发生在年轻代,速度快,频繁。

      2.Full GC/Major GC:发生在老年代, 一般也伴随Minor GC, 速度一般比Minor GC慢10倍以上。

大对象直接进入老年代:

  • 可以通过设定-XX:PretenureSizeThreshold来判断当分配的对象大于这个阈值时,则直接将其分配到老年代。
  • PretenureSizeThreshold只对Serial和ParNew收集器有效。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * PretenureSizeThreshold
  * -XX:+PrintGCDetails 打印GC信息
  * -Xms12M 起始堆大小
  * -Xmx12M 最大堆大小
  * -Xmn6M 年轻代大小
  * -XX:SurvivorRatio=6 Eden:S0:S1 = 4:1:1
  * -XX:PretenureSizeThreshold 对象超过该值,直接进入老年代,单位B
  * -XX:UseParNewGC 使用UserParNew收集器
  * jvm args:
  * -XX:UseParNewGC -XX:+PrintGCDetails -Xms12M -Xmx12M -Xmn6M -XX:SurvivorRatio=4 -XX:PretenureSizeThreshold=2097152
  */
public class PretenureSizeThreshold {
     private static final int _1M =  1024 * 1024 ;
     
     public static void main(String[] args) {
         // 分配2M, 大于PretenureSizeThreshold, 直接进入老年代
         byte [] b1 =  new byte [_1M *  3 ];
     }
}

jvm垃圾收集器与内存分配策略

其他参数介绍:

  • MaxTenuringThreshold: 在Eden区,对象在每次Minor GC后存活下来,则其年龄+1, 当存活对象年龄大于MaxTenuringThreshold时,就进入老年代。
  • HandlePromotionFailure: 空间担保机制。在发生Minor GC时,虚拟机会检测比较每次晋升到老年代的平均大小与老年代剩下的空间大小,如果大于,则进行一次Full GC;如果小于,则查看HandlePromotionFailure是否允许担保失败,若允许只进行Minor GC;若不允许,还是会进行一次Full GC。

上面就基本介绍了jvm分配回收内存策略。

不吝指正。


原文地址:http://www.open-open.com/lib/view/open1396188097934.html

Keil MDK 5.37及之后版本 安装AC5(ARMCC)编译器详细步骤 由于Keil 5.37及之后版本不再默认安装AC5(ARMCC)编译器,这就会导致由AC5编译的工程无法正常编译,往往输出窗口会提示以下信息:*** Target ‘STM32xxxx‘ uses ARM-Compiler ‘Default Compiler Version 5‘ which is not available. 阅读详情

相关推荐

Unity插件-Mirror使用方法(一)Mirror介绍

Unity Mirror 是一个专为 Unity 引擎设计的开源、社区驱动的网络库,主要用于简化多人联机游戏的开发。它最初是为了替代 Unity 原生的 UNet 系统(已被官方弃用)而创建的,因其轻量、灵活和高效的特点,成为 Unity 开发者构建多人游戏的热门选择。

qq_44501691的博客 4097

Java的四种引用类型

Java有四种引用类型:强引用、软引用、弱引用、虚引用。 1. 强引用(StrongReference) 强引用是最常用的引用。如果一个对象具有强引用,那 GC(Gabage Collection,垃圾回收)绝不会回收它。 Object obj = new Object(); // 强引用 当内存空间不足,Java虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也...

Fantasy 6999

Applied Intelligence投稿经验分享(正在投稿中)

这几天在投稿Applied Intelligence这个期刊,过程很曲折,反反复复,因此写一篇经验分享,希望能记录一下自己的过程,也能给其他人一些帮助(可以在评论区讨论),提醒一下,一定要写一些声明,不会写、不知道写啥就看第四章的第二个问题。

weixin_55988068的博客 1万+

Java数据类型:引用类型

引用类型,顾名思义,是用于存储对象引用(或称为句柄)的数据类型。引用类型不是类或者对象,只是变量的一种类型。当我们声明一个引用类型的变量时,该变量并不直接存储对象本身(如下图的变量obj1),而是存储了指向对象在内存中位置的一个地址(如下图的堆地址1这意味着,通过引用类型的变量,能够间接地操作对象。通过引用类型的变量对Java对象进行操作,赋予Java对象以生命力。通过本文的解析与示例,希望读者能更加深入地掌握引用类型,灵活运用这一强大工具,构建更加高效、健壮的Java应用程序。

epitomizelu的专栏 3835

SAP-MM-采购申请字段解析

采购申请抬头以及行项目字段解析

yanzibing99的博客 7305

S32K3xx系列DMA驱动实战:EB配置与Mcal接口应用全解析(含Adc硬件触发示例)

本文深入解析S32K3xx系列MCU的DMA驱动开发,涵盖EB工具配置与Mcal接口应用,特别包含ADC硬件触发示例。通过详细架构分析、实战配置步骤和工业级应用案例,帮助开发者掌握AUTOSAR环境下DMA高效数据传输技术,提升汽车电子和工业控制系统的性能。

weixin_29162439的博客 463

Java的4种引用类型

java为引用类型专门定义了一个类叫做。Reference是跟java垃圾回收机制息息相关的类,通过探讨Reference的实现可以更加深入的理解java的垃圾回收是怎么工作的。引用的结构图如下:引用队列是为了配合SoftReference、WeakReference、PhantomReference使用,它们三个在GC回收之前会被放到引用队列里ReferenceQueue保存下。

weixin_40482816的博客 3121

汇川H5U PLC 实现直线插补、圆弧插补、直线圆弧混合连续插补

使用汇川H5UPLC实现直线插补,圆弧插补,直线圆弧混合路径插补,通过示教可以走出复杂的路径,仅供参考学习。

weixin_39832501的博客 4773

Java中的四种引用类型

java中的四种引用类型

sugarxxc的博客 8265

NX二次开发 计算多个体的最小包围盒

多个体的最小包围盒

weixin_72680115的博客 430

OpenClaw 技术架构解析-网关层(上)

OpenClaw 网关层是架构核心中枢,承接Channel层消息,串联消息路由器、会话状态管理器等五大组件,负责消息分发、会话管理、状态统筹、上下文维护等关键职责,是连接Channel层与AI执行引擎的核心桥梁,保障多渠道交互稳定、有序运行。

wend的博客 711

java的四种引用类型

一、强引用 String s = "kkk"; s属于强引用,只要s属于根可达对象,则就算内存溢出,gc也不会回收 二、软应用 gc正常不会回收,除非内存不够用则会回收,多用于缓存机制场景;可单独开启线程监控引用队列,防止无效的软引用浪费内存; 可通过vm配置演示下面代码示例 -Xms4m -Xmx4m -XX:+PrintGC public class TestSoftReferance { private static final List<Object> TEST_

qq_19952029的博客 735

SAPIEN ManiSkill3 入门教程(一)

请注意,table.set_pose(pose) 设置的是演员在世界帧中的坐标系姿势。移除的实体可以再次添加到场景中,但已在场景中的实体则不能再次添加。显示器可以是物理的(如显示器),也可以是虚拟的(如 VNC)。我们可以通过 get_pose()、get_linear_velocity() 和 get_angular_velocity()获取演员的运动量(姿势、线速度、角速度)。现在,让我们创建一个斜坡。例如,您可能需要一个简单的碰撞形状来进行快速模拟,但却需要一个复杂的视觉形状来进行逼真的渲染。

机器人控制与仿真应用 3071

【JVM从小白学成大佬】5.垃圾收集器及内存分配策略

前面介绍了垃圾回收算法,接下来我们介绍垃圾收集器和内存分配的策略。有没有一种牛逼的收集器像银弹一样适配所有场景?很明显,不可能有,不然我也没必要单独搞一篇文章来介绍垃圾收集器了。熟悉不同收集器的优缺点,在实际的场景中灵活运用,才是王道。 在开始介绍垃圾收集器前,我们可以剧透几点: 根据不同分代的特点,收集器可能不同。有些收集器可以同时用于新生代和老年代,而有些时候,则需要分别为新生代或老年代选用...

一起理解技术趋势,沉淀长期价值 1201

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【JVM】JVM 垃圾收集器与内存分配策略

JVM 垃圾收集器与内存分配策略 由JVM内存区域可知Java运行时内存的各个区域。其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,当方法结束或者线程结束时,内存就会跟着被回收了。 而只有处于运行期间,我们才能知道程序究竟会创建哪些对象,创建多少个对象,所以Java堆和方法区这两个区域内存的分配和回收时动态的,垃圾收集器也只关注这部分内存的管理。 一.对象存活判断 1.引用计数算法 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时

ZMXQQ233的博客 363

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深入理解JVM垃圾收集器与内存分配策略

在Java虚拟机中,“垃圾”指的是内存中不再使用或不可达的对象。垃圾收集器(GC)的主要任务就是识别并回收这些垃圾对象,释放内存资源。在JVM中,垃圾收集器管理的是堆(Heap)和方法区(Method Area)中的对象,它们的生命周期是动态的,需要在运行时进行分配和回收。JVM的垃圾收集机制通过多种垃圾收集算法和策略来优化内存回收,提升程序性能。理解不同垃圾收集器的特点及内存分配策略,能够帮助开发者更好地管理Java应用的内存,减少垃圾回收带来的性能损耗。

dm菜鸟编程的专栏 1214

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JVM之垃圾收集器与内存分配回收策略(二)

JVM之垃圾收集器与内存分配回收策略(二) 上一篇JVM垃圾收集器与内存分配策略(一),下面是jdk1.7版本的垃圾收集器之间的关系,其中连线两端的两种垃圾收集器可以进行搭配使用,下面来总结一下这些收集器的一些特点以及关系。 一、Serial收集器   1、serial收集器是一个单线程的收集器,单线程说明两点:①只会使用一个CPU或者一条...

qq_40148886的博客 170

【深入理解JVM】垃圾收集器&内存分配策略

那么虚拟机要进行GC的时候,就不会管这些已经运行到安全区域的线程,当线程要脱离安全区域的时候,要自己检查系统是否已经完成了GC或者根节点枚举(这个跟GC的算法有关系),如果完成了就继续执行,如果未完成,它就必须等待收到可以安全离开安全区域的Safe Region的信号为止。简单解释一下,当线程1,线程2 是两个十分耗时的循环,并且根据HotSpot放置安全点的位置来说,上一段代码是典型的 counted loop(可数循环),也就是说每次循环回跳前是不会放置安全点的。所以这里就引入了安全点的概念。

fanday的博客 563

JVM之垃圾收集器与内存分配策略(二)

本篇文章是继JVM之垃圾收集器与内存分配策略(一)后写的,同样是笔者从《深入理解JVM虚拟机》中总结下来的,当做笔记。 GC类型以及导致Full GC的情况以及解决方法 GC类型包括: Minor GC:对新生代进行的GC; Major GC:对老年代进行的GC; Full GC:对整个堆进行的GC。 导致Full GC的情况包括: System.gc()方法的调用:建议JVM进行Fu...

博客 307

JVM内存分配策略及垃圾收集器简介

大对象是指需要连续内存空间的对象,最典型的大对象是那种很长的字符串以及数组。

weixin_46301906的博客 1190

JVM的垃圾回收算法、垃圾收集器和内存分配策略

JVM的垃圾回收算法、垃圾收集器和内存分配策略怎样判断对象是否可回收1、引用计数法2、可达性分析法引用的4种类型Java对象如何被回收回收方法区垃圾回收算法垃圾收集器内存分配和回收策略 怎样判断对象是否可回收 1、引用计数法 给对象添加一个引用计数器,每当一个地方引用,计数器加1;每当引用失效时,计数器的值就减1;当计数器为0时的对象就不可能被使用的。 当两个对象相互引用时,会导致无法回收这两个...

某某灬 246

JVM之垃圾收集器与内存分配策略

一、低延迟垃圾收集器 衡量垃圾收集器的三项最重要的指标是:内存占用、吞吐量和延迟。 Shenandoah收集器 Shenandoah的目标是实现一种能在任何堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内的垃圾收集器 工作阶段 ·初始标记(Initial Marking):与G1一样,首先标记与GC Roots直接关联的对象,这个阶段仍 是“Stop The World”的,但停顿时间与堆...

HerryBody 250
上一篇: 关于用户密码的简单加密(DES+MD5)与复杂加密(自己想的)
下一篇: 操作系统原理学习总结
breaknull
博客等级 码龄14年 15粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值