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

涪陵网站建设 优帮云青岛建设房地产招聘信息网站

涪陵网站建设 优帮云,青岛建设房地产招聘信息网站,优化网站排名公司,长春高端网站建设一、引言 我们学习了Java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭。栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来就已知的…

一、引言

我们学习了Java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭。栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来就已知的,因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑如何回收的问题,当方法结束或者线程结束时,内存自然就跟随着回收了。

而Java堆和方法区这两个区域则有着很显著的不确定性:一个接口的多个实现类需要的内存可能会不一样,一个方法所执行的不同条件分支所需要的内存也可能不一样,只有处于运行期间,我们才能知道程序究竟会创建哪些对象,创建多少个对象,这部分内存的分配和回收是动态的。垃圾收集器所关注的正是这部分内存该如何管理,一般讨论“内存”分配与回收也仅仅特指这一部分。

二、引用计数算法

引用计数算法是一种内存管理算法,用于追踪对象的引用数量。它的基本原理是为每个对象维护一个计数器,记录当前有多少个指针指向该对象。当计数器的值变为0时,表示该对象不再被引用,可以被回收。

引用计数算法的实现思路如下:

  1. 在对象中添加一个引用计数器,初始值为0。
  2. 当有一个指针指向该对象时,引用计数器加1。
  3. 当一个指针不再指向该对象时,引用计数器减1。
  4. 当引用计数器的值为0时,表示没有指针指向该对象,可以将该对象回收。

引用计数算法的优点:

  1. 实时性:引用计数算法可以实时地进行内存回收,不需要等待垃圾回收器的运行。
  2. 简单高效:引用计数算法的实现相对简单,不需要遍历整个对象图,只需要维护计数器即可。

引用计数算法的缺点:

  1. 循环引用问题:当存在循环引用时,引用计数算法无法正确地回收内存。例如,对象A和对象B相互引用,它们的引用计数器都不会变为0,导致内存泄漏。
  2. 计数器更新开销:每次引用发生变化时,都需要更新计数器,导致额外的开销。

因为引用计数算法存在循环引用问题,所以现代的垃圾回收器往往不使用纯粹的引用计数算法,而是采用其他算法(如标记-清除算法、复制算法、标记-整理算法等)与引用计数算法结合,来解决循环引用的回收问题。

三、代码分析

以下是一个简单的引用计数算法的代码案例:

class ReferenceCounting {private int count; // 引用计数器public ReferenceCounting() {count = 0;}public void addReference() {count++;}public void removeReference() {count--;}public int getCount() {return count;}
}
class Object {private ReferenceCounting refCount; // 引用计数对象public Object() {refCount = new ReferenceCounting();refCount.addReference(); // 对象创建时增加引用计数}public void addReference() {refCount.addReference();}public void removeReference() {refCount.removeReference();if (refCount.getCount() == 0) {// 引用计数为0时执行回收操作System.out.println("Object is reclaimed.");// 执行回收操作}}
}
public class ReferenceCountingDemo {public static void main(String[] args) {Object obj1 = new Object(); // 创建对象1Object obj2 = new Object(); // 创建对象2obj1.addReference(); // obj1引用计数加1obj1.addReference(); // obj1引用计数加1obj2.addReference(); // obj2引用计数加1obj1.removeReference(); // obj1引用计数减1obj1.removeReference(); // obj1引用计数减1,计数为0,执行回收操作obj2.removeReference(); // obj2引用计数减1,计数不为0,不执行回收操作}
}

在上述代码中,ReferenceCounting类是引用计数器类,用于记录对象被引用的次数。Object类是被引用的对象类,其中包含了一个ReferenceCounting对象。当创建对象时,引用计数加1,当移除对象引用时,引用计数减1。当引用计数为0时,表示对象不再被引用,可以执行回收操作。 在ReferenceCountingDemo类的main方法中,我们创建了两个对象obj1obj2,分别增加和减少引用计数,演示了引用计数算法的基本原理。

在下一个案例前,我们首先要学会在IDEA中输出gc日志信息:

循环引用代码分析:

class A {private B b;public void setB(B b) {this.b = b;}
}
class B {private A a;public void setA(A a) {this.a = a;}
}
public class ReferenceCountingDemo {public static void main(String[] args) {A a = new A();B b = new B();a.setB(b);b.setA(a);// 解除对A和B对象的引用a = null;b = null;// 这里无法回收A和B对象,因为它们之间存在循环引用System.gc();}
}

在上述案例中,我们创建了两个类A和B,它们分别有一个成员变量用于相互引用。在main方法中,我们创建了一个A对象和一个B对象,并通过setBsetA方法将它们相互引用起来。但是,由于它们之间存在循环引用,即A对象引用B对象,B对象引用A对象,导致它们的引用计数器都不会变为0,无法被回收。

尽管在最后我们将ab设置为null解除了对它们的引用,但由于循环引用的存在,它们的引用计数仍然不为0,无法执行回收操作。

 控制台输出:

从运行结果可以看到内存回收日志包含“Pause Full (System.gc()) 2M->0M(14M) 3.909ms”,意味着虚拟机并没有因为这两个对象互相引用就放弃回收它们,这也从侧面说明了Java虚拟机并不是通过引用计数算法来判断对象是否存活的。

http://www.yayakq.cn/news/515242/

相关文章:

  • 建构网站网站制作关键
  • 重庆做网站及公众号公司广州 建设 招聘信息网站
  • 行政审批局政务服务网站建设情况wordpress的数据库
  • 陕西最好的云营销网站建设公司小程序商城开发华网天下优秀
  • 求推荐专门做借条的网站苏州wordpress
  • 济阳网站建设哪家好网站网站建设策划书
  • 天津网站设计成功柚米个人网店和网站的区别
  • 免费做调查的网站建立网站根目录下
  • 微网站建设讯息美工设计师是做什么的
  • 怎样做相亲网站做网站如何给图片命名
  • 个人免费网站开发自己在线制作logo免费标智客
  • 金华网站定制公司做贷款网站犯法吗
  • 网站后台青岛城乡建设局网站
  • 阿里巴巴的网站怎么做的seo软件推广哪个好
  • 网站建设哪家g辽宁建设工程招投标信息网
  • 网站建设w亿玛酷1负责景县住房和城乡规划建设局网站
  • 大良外贸网站设计企业培训网
  • 网站功能模块设计做视频招标的网站有哪些
  • 照片做视频的软件 模板下载网站好搜索引擎的网站推广方式
  • 珠海市研发网站建设led行业网站源码
  • 医院网站前置审核品牌策划是做什么
  • 美食网站开发的目的常州网络推广
  • wordpress+直接连接搜索引擎关键词优化技巧
  • 网站优化销售话术微网站如何做推广方案设计
  • 十大职业资格培训机构站长工具seo综合查询方法
  • 唐山网站定制asp.net学校网站整站系统源码
  • 网站浮动窗口怎么做芙蓉网站制作
  • c语言开发网站教程绵阳东原建设工程有限公司网站
  • 商城网站怎么做内链网页版微信官方下载
  • 网站推广公司黄页wordpress转pdf