当前位置: 首页 > news >正文

JVM调优总结(四)-垃圾回收面临的问题

如何区分垃圾

 

    上面说到的“引用计数”法,通过统计控制生成对象和删除对象时的引用数来判断。垃圾回收程序收集计数为0的对象即可。但是这种方法无法解决循环引用。所以,后来实现的垃圾判断算法中,都是从程序运行的根节点出发,遍历整个对象引用,查找存活的对象。那么在这种方式的实现中,垃圾回收从哪儿开始的呢?即,从哪儿开始查找哪些对象是正在被当前系统使用的。上面分析的堆和栈的区别,其中栈是真正进行程序执行地方,所以要获取哪些对象正在被使用,则需要从Java栈开始。同时,一个栈是与一个线程对应的,因此,如果有多个线程的话,则必须对这些线程对应的所有的栈进行检查。

    同时,除了栈外,还有系统运行时的寄存器等,也是存储程序运行数据的。这样,以栈或寄存器中的引用为起点,我们可以找到堆中的对象,又从这些对象找到对堆中其他对象的引用,这种引用逐步扩展,最终以null引用或者基本类型结束,这样就形成了一颗以Java栈中引用所对应的对象为根节点的一颗对象树,如果栈中有多个引用,则最终会形成多颗对象树。在这些对象树上的对象,都是当前系统运行所需要的对象,不能被垃圾回收。而其他剩余对象,则可以视为无法被引用到的对象,可以被当做垃圾进行回收。

因此,垃圾回收的起点是一些根对象(java栈, 静态变量, 寄存器...)。而最简单的Java栈就是Java程序执行的main函数。这种回收方式,也是上面提到的“标记-清除”的回收方式

 

 

如何处理碎片

   由于不同Java对象存活时间是不一定的,因此,在程序运行一段时间以后,如果不进行内存整理,就会出现零散的内存碎片。碎片最直接的问题就是会导致无法分配大块的内存空间,以及程序运行效率降低。所以,在上面提到的基本垃圾回收算法中,“复制”方式和“标记-整理”方式,都可以解决碎片的问题。

 

 

如何解决同时存在的对象创建和对象回收问题

    垃圾回收线程是回收内存的,而程序运行线程则是消耗(或分配)内存的,一个回收内存,一个分配内存,从这点看,两者是矛盾的。因此,在现有的垃圾回收方式中,要进行垃圾回收前,一般都需要暂停整个应用(即:暂停内存的分配),然后进行垃圾回收,回收完成后再继续应用。这种实现方式是最直接,而且最有效的解决二者矛盾的方式。

但是这种方式有一个很明显的弊端,就是当堆空间持续增大时,垃圾回收的时间也将会相应的持续增大,对应应用暂停的时间也会相应的增大。一些对相应时间要求很高的应用,比如最大暂停时间要求是几百毫秒,那么当堆空间大于几个G时,就很有可能超过这个限制,在这种情况下,垃圾回收将会成为系统运行的一个瓶颈。为解决这种矛盾,有了并发垃圾回收算法,使用这种算法,垃圾回收线程与程序运行线程同时运行。在这种方式下,解决了暂停的问题,但是因为需要在新生成对象的同时又要回收对象,算法复杂性会大大增加,系统的处理能力也会相应降低,同时,“碎片”问题将会比较难解决。

转载于:https://www.cnblogs.com/barrywxx/p/4351462.html

相关文章:

  • Android代码报错:setContentView(R.layout.activity_main)
  • ccf 门禁系统
  • Swing学习总结
  • VB - 变量
  • 图片压缩,别问我是谁,请叫我雷锋
  • C++单例模式实例
  • Action(8):Error -27728:Step download timeout(120 seconds)has expired when downloading
  • 千位数减百位数不退位 区间代换
  • C# 第三次作业
  • Maven常用命令总结
  • ecshop开发日志之手机端虚拟商品自动发货
  • C++ 指针悬挂和赋值操作符的重载,拷贝构造函数实现
  • WCF-终结点之消息路由示例
  • Android学习笔记(四六):互联网通信-文件下载
  • 封装WebService的APM为Async、Await模式利于Asp.Net页面调用
  • Apache Spark Streaming 使用实例
  • Apache的基本使用
  • gulp 教程
  • JavaScript 基础知识 - 入门篇(一)
  • js对象的深浅拷贝
  • Kibana配置logstash,报表一体化
  • MQ框架的比较
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • SwizzleMethod 黑魔法
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 彻底搞懂浏览器Event-loop
  • 使用权重正则化较少模型过拟合
  • 微服务框架lagom
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 阿里云ACE认证学习知识点梳理
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #pragma multi_compile #pragma shader_feature
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (13):Silverlight 2 数据与通信之WebRequest
  • (rabbitmq的高级特性)消息可靠性
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (力扣)1314.矩阵区域和
  • (十八)三元表达式和列表解析
  • (一)kafka实战——kafka源码编译启动
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .Net Web窗口页属性
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 使用反射注册事件
  • .NET6 命令行启动及发布单个Exe文件
  • @vue/cli脚手架