下面是RednaxelaFX的回答:

1.最基本的纯引用计数方式的自动内存管理可以做到实时释放死对象,但却无法处理存在循环引用的对象图的释放。

这个问题一定程度上可以通过引入弱引用的概念来解决,但通用的能处理带循环引用对象图的引用计数都是有别的管理方式备份的(通常是某种tracing GC,例如mark-sweep;也有名为“trial-deletion”的循环检测方法,但这个通常比tracing性能更差所以用得较少),例如CPython使用以引用计数为主、mark-sweep为辅的方式,Adobe Flash的ActionScript VM 2(AVM2)也是以延迟引用计数(DRC)为主、增量/保守式mark-sweep为辅。反之,像C++的std::shared_ptr就是纯引用计数,无法靠自己处理带循环引用的对象图,而必须靠程序员自己小心使用,在必要的地方用std::weak_ptr来破除循环;CPython在2.0之前也使用纯引用计数,无法处理循环引用,只能等着泄漏内存。既然通用的引用计数还得用tracing GC来备份,实现这样的自动内存管理等于得实现两份,想偷懒的话还不如一开始就只实现某种tracing GC,例如mark-sweep。

2.最基本的纯引用计数方式对引用计数器的操作非常频繁,这里有额外开销,至于是否严重到成问题就看具体应用的可忍受程度。在内存充裕的前提下,基本的tracing GC比基本的引用计数方式的性能更好(特别是从throughput角度看),不需要做冗余的计数器更新。同时,在多线程环境下引用计数器可能成为线程间共享的数据,需要做同步保护(这里把原子更新算同步保护的一种),这也是个额外开销的来源;因为tracing GC不需要维护引用计数器所以也就没有这种同步的开销。引用计数的这些性能缺点可以通过一些高级变种来缓解,例如前面提到AVM2的延迟引用计数,只记录堆上对象之间的引用计数而不记录栈上(主要是表达式临时值)对对象的引用计数,以此减少对计数器的更新次数来提高性能。详情可参考文档:MMgc | MDN。这些引用计数的高级变种通常意味着一定程度的延迟释放,跟楼主想实时释放的初衷就不符了。另一方面,虽然最基本的tracing GC会有较长的延迟,但它们也有高级变种,可以并行、并发、增量式执行,降低延迟;也有办法实现thread-local GC来应对像是“请求-响应”式的Web应用批量释放一个线程临时分配的对象的需求。

3.如果选用tracing GC来实现自动内存管理,它是不显式维护对象的引用计数的,也就没有“引用计数到0”的概念。所以基于tracing GC的JVM或其它语言的运行时环境自然不会“引用计数到0就释放对象”。

4.引用计数方式其实也有经典的卡顿情况。例子之一就是一个对象个数很多、引用链很长的对象图假如只是被一个引用而留活,那么那个引用一死就会引发大量对象扎堆释放(但却不是“批量释放”,开销不同),这一样会引起卡顿。单纯讨论最坏情况的话其实引用计数也有这样糟糕的一面。纯人工的malloc()/free()或new/delete可以让程序员人肉找出生命周期相同的对象,然后利用诸如arena之类的方式为它们分配内存,就可以它们死的时候真正批量释放掉它们,这样就很高效;但纯引用计数却不是这么回事。使用引用计数会否遇到这种卡顿全看你的程序里对象图的引用关系是怎样的。

原文:http://www.cnblogs.com/binyue/p/4311232.html

java 内存管理 知乎_[知乎]Java 语言的 GC 为什么不实时释放内存?相关推荐

  1. java 及时释放内存_Java 等语言的 GC 为什么不实时释放内存?

    最基本的纯引用计数方式的自动内存管理可以做到实时释放死对象,但却无法处理存在循环引用的对象图的释放.这个问题一定程度上可以通过引入弱引用的概念来解决,但通用的能处理带循环引用对象图的引用计数都是有别的 ...

  2. c语言结构体数组内存大小,如何为C语言的结构体数组分配/释放内存?

    如何为C语言的结构体数组分配/释放内存? struct emp { char name[10]; float salary; }; int main(int argc,char* argv[]) { ...

  3. 怎样下载java知乎_怎样下载JAVA?

    Java 开发环境配置 在本回答中我们将为大家介绍如何搭建Java开发环境.Windows 上安装开发环境 Linux 上安装开发环境 安装 Eclipse 运行 Java window系统安装jav ...

  4. 机器学习模型 知乎_知乎CTO李大海:谢邀,来分享下内容社区的AI架构搭建与应用...

    谢邀!知乎 CTO 来分享下内容社区的 AI 架构搭建与应用. 「在信息爆炸的互联网海洋中,有价值的信息仍然是稀缺的」.知乎的诞生源于这样一个非常简单的初心. 而在挖掘真正有价值的信息过程中,知乎很好 ...

  5. java方法区对象类型_浅谈Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

  6. 运行时错误7内存溢出_分别从运行时和GC的角度看JAVA8内存管理

    运行时区域 1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机概念模型里(概念模型,各种虚拟机 ...

  7. 详解JVM内存管理与垃圾回收机制5 - Java中的4种引用类型

    在Java语言中,除了基础数据类型的变量以外,其他的都是引用类型,指向各种不同的对象.在前文我们也已经知道,Java中的引用可以是认为对指针的封装,这个指针中存储的值代表的是另外一块内存的起始地址(对 ...

  8. go还是python 知乎_知乎用Go替代Python

    说不上哪个语言会比另一个语言更好.只能说某个语言在某个方面处理某些问题更具有优势吧. 大概每个开发人员应该都会认为自己使用的语言是世界最好的语言吧.这都相对来说的.对于每个人应该都是不同的. 众所周知 ...

  9. java 发送短信 多通道_一种Java卡多通道临时对象管理方法与流程

    本发明涉及Java智能卡领域,具体涉及一种Java卡多通道临时对象管理方法. 背景技术: :JavaCard规范支持逻辑通道的概念,允许最多智能卡中的16个应用程序会话同时开启,每个逻辑通道一个会话. ...

最新文章

  1. Android中Activity的启动流程和组织管理方式(Backstack、Task)
  2. jquery学习手记(9)事件基础知识
  3. css background-position
  4. 逻辑漏洞——会话管理问题
  5. 占据语音入口?苹果或将在2020年WWDC上推出SiriOS
  6. 携程Apollo(阿波罗)配置中心在Spring Boot项目快速集成
  7. WebGrid Enterprise免费下载
  8. 移远ec20 4g模块linux驱动移植,Hi3798移植4G模块(移远EC20)
  9. 浙大 博士 计算机视觉,95后浙大博士生开发全新视图合成系统Neural Body,稀疏视角输入即可合成360°人体视图|专访...
  10. 对比stm32,arm9研究方向
  11. 专家有料 | 李中文:美团软件成分安全分析(SCA)能力的建设与演进
  12. 教你快速批量查询顺丰快递物流的两种方法
  13. 如何计算根号之牛顿迭代法
  14. matlab三相异步电动机仿真,三相异步电动机的MATLAB仿真研究
  15. 数据链路层的有那三个基本问题?为什么都必须加以解决?
  16. 【分布式计算:原理、算法和系统】第二章 分布式计算模型
  17. 最新2021年自由钱江路《自由钱江路投@资课》值得学习吗
  18. 网路层协议——IGMP协议
  19. LENZE变频器调试软件L-forc Engineer v2 送资料部分手册
  20. 小说分销系统,边看小说边赚钱,19年最火新项目

热门文章

  1. OCP学习和培训ppt汇总
  2. Loadrunner中web_reg_save_param的使用详解
  3. Assets.car 解压工具 cartool 使用报错 segmentation fault cartool 解决方案
  4. coursera 视频总是缓冲或者无法观看,有什么方法解决?
  5. 德勤元宇宙综观:愿景、技术和应对
  6. 【报告分享】食品饮料行业供应链发展与渠道变革趋势.pdf(附下载链接)
  7. python遍历本地文件系统
  8. 悬浮球不用权限_Android 实现无需权限的悬浮球效果,可适配至Android 10
  9. 修改个人信息 python_python函数练习——个人信息修改
  10. 1-java学习笔记