垃圾收集器与Java编程

Java垃圾收集器之CMS收集器编程 CMS收集器的特点是在垃圾收集过程中,尽量减少应用程序的停顿时间。这样,在垃圾收集过程中,应用程序的执行可以继续进行,减少了停顿时间对应用程序性能的影响。垃圾收集器是Java虚拟机中的重要组件,用于自动管理内存中的垃圾对象。需要注意的是,CMS收集器是一种并发的垃圾收集器,它的运行会占用一部分CPU资源。因此,在使用CMS收集器时,需要根据应用程序的实际情况来配置虚拟机的内存和CPU资源,以达到最佳的性能和吞吐量。通过并发标记和并发清除的策略,它能够在垃圾收集过程中尽量减少应用程序的停顿时间。 阅读详情
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> 垃圾收集器(Garbage Collector,GC)对Java程序员来说,基本上是透明的,但是一个优秀的Java程序员必须了解GC的工作原理、如何优化GC的性能、如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统、实时系统等,只有全面提升内存的管理效率 ,才能提高整个应用程序的性能。本篇文章首先简单介绍GC的工作原理之后,然后再对GC的几个关键问题进行深入探讨,最后提出一些Java程序设计建议,从GC角度提高Java程序的性能。   GC的基本原理   Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。   对于程序员来说,分配对象使用new关键字;释放对象时,只要将对象所有引用赋值为null,让程序不能够再访问到这个对象,我们称该对象为"不可达的"。GC将负责回收所有"不可达"对象的内存空间。   对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象(详见 参考资料1 )。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。但是,为了保证GC能够在不同平台实现的问题,Java规范对GC的很多行为都没有进行严格的规定。例如,对于采用什么类型的回收算法、什么时候进行回收等重要问题都没有明确的规定。因此,不同的JVM的实现者往往有不同的实现算法。这也给Java程序员的开发带来行多不确定性。本文研究了几个与GC工作相关的问题,努力减少这种不确定性给Java程序带来的负面影响。   增量式GC( Incremental GC )   GC在JVM中通常是由一个或一组进程来实现的,它本身也和用户程序一样占用heap空间,运行时也占用CPU。当GC进程运行时,应用程序停止运行。因此,当GC运行时间较长时,用户能够感到Java程序的停顿,另外一方面,如果GC运行时间太短,则可能对象回收率太低,这意味着还有很多应该回收的对象没有被回收,仍然占用大量内存。因此,在设计GC的时候,就必须在停顿时间和回收率之间进行权衡。一个好的GC实现允许用户定义自己所需要的设置,例如有些内存有限有设备,对内存的使用量非常敏感,希望GC能够准确的回收内存,它并不在意程序速度的放慢。另外一些实时网络游戏,就不能够允许程序有长时间的中断。增量式GC就是通过一定的回收算法,把一个长时间的中断,划分为很多个小的中断,通过这种方式减少GC对用户程序的影响。虽然,增量式GC在整体性能上可能不如普通GC的效率高,但是它能够减少程序的最长停顿时间。   Sun JDK提供的HotSpot JVM就能支持增量式GC。HotSpot JVM缺省GC方式为不使用增量GC,为了启动增量GC,我们必须在运行Java程序时增加-Xincgc的参数。HotSpot JVM增量式GC的实现是采用Train GC算法。它的基本想法就是,将堆中的所有对象按照创建和使用情况进行分组(分层),将使用频繁高和具有相关性的对象放在一队中,随着程序的运行,不断对组进行调整。当GC运行时,它总是先回收最老的(最近很少访问的)的对象,如果整组都为可回收对象,GC将整组回收。这样,每次GC运行只回收一定比例的不可达对象,保证程序的顺畅运行。   详解finalize函数   finalize是位于Object类的一个方法,该方法的访问修饰符为protected,由于所有类为Object的子类,因此用户类很容易访问到这个方法。由于,finalize函数没有自动实现链式调用,我们必须手动的实现,因此finalize函数的最后一个语句通常是super.finalize()。通过这种方式,我们可以实现从下到上实现finalize的调用,即先释放自己的资源,然后再释放父类的资源。   根据Java语言规范,JVM保证调用finalize函数之前,这个对象是不可达的,但是JVM不保证这个函数一定会被调用。另外,规范还保证finalize函数最多运行一次。   很多Java初学者会认为这个方法类似与C 中的析构函数,将很多对象、资源的释放都放在这一函数里面。其实,这不是一种很好的方式。原因有三,其一,GC为了能够支持finalize函数,要对覆盖这个函数的对象作很多附加的工作。其二,在finalize运行完成之后,该对象可能变成可达的,GC还要再检查一次该对象是否是可达的。因此,使用finalize会降低GC的运行性能。其三,由于GC调用finalize的时间是不确定的,因此通过这种方式释放资源也是不确定的。   通常,finalize用于一些不容易控制、并且非常重要资源的释放,例如一些I/O的操作,数据的连接。这些资源的释放对整个应用程序是非常关键的。在这种情况下,程序员应该以通过程序本身管理(包括释放)这些资源为主,以finalize函数释放资源方式为辅,形成一种双保险的管理机制,而不应该仅仅依靠finalize来释放资源。 下面给出一个例子说明,finalize函数被调用以后,仍然可能是可达的,同时也可说明一个对象的finalize只可能运行一次。   class MyObject{    Test main; //记录Test对象,在finalize中时用于恢复可达性    public MyObject(Test t)    {    main=t; //保存Test 对象    }    protected void finalize()    {    main.ref=this;// 恢复本对象,让本对象可达    System.out.println("This is finalize");//用于测试finalize只运行一次    }   }   class Test {    MyObject ref;    public static void main(String[] args) {    Test test=new Test();    test.ref=new MyObject(test);    test.ref=null; //MyObject对象为不可达对象,finalize将被调用    System.gc();    if (test.ref!=null) System.out.println("My Object还活着");    }   }   运行结果:   This is finalize   MyObject还活着   此例子中,需要注意的是虽然MyObject对象在finalize中变成可达对象,但是下次回收时候,finalize却不再被调用,因为finalize函数最多只调用一次。   程序如何与GC进行交互   Java2增强了内存管理功能, 增加了一个java.lang.ref包,其中定义了三种引用类。这三种引用类分别为SoftReference、WeakReference和PhantomReference。通过使用这些引用类,程序员可以在一定程度与GC进行交互,以便改善GC的工作效率。这些引用类的引用强度介于可达对象和不可达对象之间。   创建一个引用对象也非常容易,例如如果你需要创建一个Soft Reference对象,那么首先创建一个对象,并采用普通引用方式(可达对象);然后再创建一个SoftReference引用该对象;最后将普通引用设置为null。通过这种方式,这个对象就只有一个Soft Reference引用。同时,我们称这个对象为Soft Reference 对象。   Soft Reference的主要特点是据有较强的引用功能。只有当内存不够的时候,才进行回收这类内存,因此在内存足够的时候,它们通常不被回收。另外,这些引用对象还能保证在Java抛出OutOfMemory 异常之前,被设置为null。它可以用于实现一些常用图片的缓存,实现Cache的功能,保证最大限度的使用内存而不引起OutOfMemory。以下给出这种引用类型的使用伪代码;   //申请一个图像对象   Image image=new Image();//创建Image对象   …   //使用 image   …   //使用完了image,将它设置为soft 引用类型,并且释放强引用;   SoftReference sr=new SoftReference(image);   image=null;    …    //下次使用时    if (sr!=null) image=sr.get();    else{    //由于GC由于低内存,已释放image,因此需要重新装载;    image=new Image();   sr=new SoftReference(image);   }   Weak引用对象与Soft引用对象的最大不同就在于:GC在进行回收时,需要通过算法检查是否回收Soft引用对象,而对于Weak引用对象,GC总是进行回收。Weak引用对象更容易、更快被GC回收。虽然,GC在运行时一定回收Weak对象,但是复杂关系的Weak对象群常常需要好几次GC的运行才能完成。Weak引用对象常常用于Map结构中,引用数据量较大的对象,一旦该对象的强引用为null时,GC能够快速地回收该对象空间。   Phantom引用的用途较少,主要用于辅助finalize函数的使用。Phantom对象指一些对象,它们执行完了finalize函数,并为不可达对象,但是它们还没有被GC回收。这种对象可以辅助finalize进行一些后期的回收工作,我们通过覆盖Reference的clear()方法,增强资源回收机制的灵活性。   一些Java编码的建议   根据GC的工作原理,我们可以通过一些技巧和方式,让GC运行更加有效率,更加符合应用程序的要求。以下就是一些程序设计的几点建议。   1.最基本的建议就是尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null。我们在使用这种方式时候,必须特别注意一些复杂的对象图,例如数组,队列,树,图等,这些对象之间有相互引用关系较为复杂。对于这类对象,GC回收它们一般效率较低。如果程序允许,尽早将不用的引用对象赋为null。这样可以加速GC的工作。   2.尽量少用finalize函数。finalize函数是Java提供给程序员一个释放对象或资源的机会。但是,它会加大GC的工作量,因此尽量少采用finalize方式回收资源。   3.如果需要使用经常使用的图片,可以使用soft应用类型。它可以尽可能将图片保存在内存中,供程序调用,而不引起OutOfMemory。   4.注意集合数据类型,包括数组,树,图,链表等数据结构,这些数据结构对GC来说,回收更为复杂。另外,注意一些全局的变量,以及一些静态变量。这些变量往往容易引起悬挂对象(dangling reference),造成内存浪费。   5.当程序有一定的等待时间,程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。使用增量式GC可以缩短Java程序的暂停时间。
Java并行垃圾收集器Parallel Scavenge的使用与编程 需要注意的是,Parallel Scavenge收集器适用于长时间执行的应用程序,因此在短时间执行的应用程序中可能不会体现出其优势。另外,由于Parallel Scavenge注重吞吐量而不是低延迟,因此对于对响应时间要求较高的应用程序,可能需要考虑其他的垃圾收集器选项。Parallel Scavenge收集器是一种针对长时间执行的应用程序而设计的垃圾收集器。总结而言,Parallel Scavenge收集器是一种针对长时间执行的Java应用程序而设计的并行垃圾收集器。在上面的示例中,我们通过使用。 阅读详情

相关推荐

Java垃圾收集器:Serial收集器 编程

它将新生代分为一个Eden空间和两个Survivor空间,根据对象的存活情况将对象复制到不同的Survivor空间中,并且经过多次垃圾收集后,仍然存活的对象将被晋升到老年代。Serial收集器还有一个重要的特点是它采用的是"标记-压缩"算法来进行老年代的垃圾回收。在老年代中,Serial收集器使用标记阶段标记出存活的对象,然后进行压缩操作,将存活的对象向一端移动,以便为新的对象分配连续的内存空间。它的特点是单线程执行、使用复制算法进行新生代的垃圾回收,以及使用"标记-压缩"算法进行老年代的垃圾回收。

CyberLynxO的博客 152

垃圾收集器GC与Java编程

Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。 对于程序员来说,分配对象使用new关键字;释放对象时,只要将对象所有引用赋值为null,让程序不能够再访问到这个对象,我们称该对象为”不可达的”。GC将负责回收所有”不可达”对象的内存空间。 对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所

太多的虚幻 9915

Java垃圾收集器:ParNew收集器的编程指南

通过配置相关的Java虚拟机参数,我们可以启用ParNew收集器,并使用多线程并行地进行新生代的垃圾回收。ParNew收集器是Java虚拟机中的一种垃圾收集器,用于新生代的垃圾回收。它是基于标记-复制算法的收集器,具有多线程的能力,可以并行地进行垃圾回收操作。本文将介绍ParNew收集器的使用方法,并提供相关的示例代码。在垃圾回收过程中,首先进行标记阶段,遍历所有的根对象,并标记所有与根对象可达的对象。要使用ParNew收集器,首先需要在Java虚拟机的启动参数中进行相应的配置。ParNew收集器的配置。

CyberBladeX的博客 234

垃圾收集器与Java编程(转载)

欧阳辰 (yeekee@sina.com), 周欣 (zhouxin@sei.pku.edu.cn), 转自:http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak2/index.html 简介: 垃圾收集器(Garbage Collector,GC)对Java程序员来说,基本 上是透明的,但是一个优秀的Java程序员必须了解GC

wiy_dawn的博客 281

从XOOPIC.zip到等离子体模拟:PIC方法核心原理与实战指南

粒子网格法(Particle-in-Cell, PIC)是计算等离子体物理和粒子束模拟领域的核心数值方法,它通过宏粒子代表大量真实粒子,并结合场求解与粒子推进的迭代循环,高效模拟带电粒子在电磁场中的集体行为。其技术价值在于能够处理多尺度、非线性的复杂等离子体动力学问题,广泛应用于核聚变、粒子加速器、空间物理等前沿研究。本文以经典开源PIC代码XOOPIC为例,深入解析其从编译配置、输入文件设计到结果可视化的完整工程实践流程,特别针对Linux环境下的编译依赖、参数调试等常见挑战提供解决方案,并探讨了从二维3

congji3817的博客 326

ROS 2 Jazzy与Gazebo Harmonic仿真实战:从零搭建机器人仿真环境与高级应用

本文详细介绍了如何使用ROS 2 Jazzy和Gazebo Harmonic从零搭建机器人仿真环境,涵盖环境配置、传感器集成、多机器人协同和GPU加速优化等高级应用。通过实战案例和性能调优技巧,帮助开发者高效构建可靠的机器人仿真系统,提升开发效率。

h9j8k7l6m5n的博客 1220

ea和java_垃圾收集器与Java编程(转)

垃圾收集器(Garbage Collector,GC)对Java程序员来说,基本 上是透明的,但是一个优秀的Java程序员必须了解GC的工作原理、如何优化GC的性能、如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统、实时系统等,只有全面提升内存的管理效率 ,才能提高整个应用程序的性能。本篇文章首先简单介绍GC的工作原理之后,然后再对GC的几个关键问题进行深入探讨,最后提出...

weixin_32709413的博客 106

MCGS触摸屏Modbus TCP通讯实战:从寄存器写入到字符串处理的完整代码解析

本文详细解析了MCGS触摸屏通过Modbus TCP协议实现寄存器写入和字符串处理的完整代码,涵盖单寄存器写入、多寄存器写入及字符串传输等核心技术。文章还提供了MCGS组态环境中的实战配置步骤和常见问题排查方法,帮助开发者快速掌握工业自动化通讯的关键技术。

study的专栏 760

Java编程中的JVM垃圾收集器:CMS、G1与ZGC解析

CMS、G1和ZGC作为Java虚拟机中重要的垃圾收集器,各有其特点和适用场景。CMS适合对响应时间有高要求的应用;G1则在平衡吞吐量和低延迟方面表现出色;而ZGC则代表了未来垃圾收集技术的发展方向,致力于实现极低的延迟。在实际应用中,开发者应根据具体需求和硬件环境选择合适的垃圾收集器,以优化Java程序的性能。

526

sql server安装并SSMS连接

  SQL Server是一种广泛应用于网络业务数据处理的关系型数据库管理系统。SQL Server 2016是微软公司研发的新一代旗舰级数据库和分析平台,突出高级分析和丰富可视化,并融合了关键创新功能。其可提供对企业基础架构最高级别的支持,专门针对关键业务应用的多种功能与解决方案提供最高级别的可用性,并提供更多、更全面的功能以满足不同人群对数据的需求,包括支持来自不同网络环境的数据交互、全面的自助分析等创新功能。百度搜索sql server,在官网下载 地址是:SQL Server 下载| Microso

jiankang66的博客 5187

全志 T527_Android13 编译 [ 避坑必看 ]

Swap 概念: Linux中Swap(即:交换分区),类似于Windows的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。它的功能就是在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行。当输入编译命令make -j16 的时候,会有如下提示,这是官方建议通过减少编译线程来解决编译时消耗内存过大的问题。Android 13 系统的编译流程,编译一共分为两部分:内核编译与 Android 编译。

公众号:嵌入式分享 2113

Java编程思想学习笔记(5)--垃圾收集器

看到垃圾收集器这里,内容比较多,不太理解,先写出来梳理一下一、为什么要使用垃圾收集器引入垃圾收集器使得Java程序员不需要关心内存管理的问题,减少了c++程序员经常出现的内存泄露的问题,有效使用空闲内存。

子非仪的博客 808

Oracle19c-集群节点重新添加

Oracle RAC集群在极端情况下,如硬件、主机,集群软件损坏,导致集群节点永久无法使用,需要对集群节点进行修复,删除节点集群信息并重新加入集群,以恢复集群原有的架构。 本文主要讲述一套两节点的Oracle19c RAC集群,节点一orcl01由于主机异常无法正常启动,在对主机进行重装之后,需要将orcl01节点重新加入集群的操作步骤。环境信息: 操作系统:Linux 7 RAC集群:19C 主机节点:orcl0...

sinat_36757755的博客 2352

技巧:Java垃圾收集器使用小诀窍-Java基础-Java-编程开发

google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";google_ad_width = 336;google_ad_height = 280;//<script type="text/javascript"

java专栏 342

从CCD数据上报看wxHOOK的封号风险与规避

本文深入分析了微信CCD数据上报机制对wxHOOK的检测逻辑与封号风险,揭示了调试器路径暴露、非白名单DLL加载和内存校验失败等关键风险点。通过实战案例和规避方案,帮助开发者理解如何安全使用wxHOOK技术,避免封号风险,包括内存镜像欺骗、内核级隐蔽和硬件辅助方案等高级技巧。

weixin_27875131的博客 635

从零开始:用Python搭建你的第一个加密货币量化交易机器人(附完整代码)

本文详细介绍了如何使用Python从零开始搭建一个加密货币量化交易机器人,涵盖环境准备、交易所API连接、基础交易策略实现、回测系统构建以及实盘部署等关键步骤。通过完整的代码示例,帮助读者快速掌握数字货币量化交易的核心技术,适合有一定编程基础的投资者入门。

weixin_30415113的博客 466

JAVA 编程语言 JDK 8 默认用的是哪款 GC 垃圾收集器

因为 JDK8 还是市场占有率最高的,所以针对这个版本我做了深入的探索。已经很成熟了,所以直接替换了旧的收集器,所以 JDK 7u4 以后的 7 和 JDK 8 老年代默认使用的都是。好的那么接下来开启 GC 之旅,这个"别名"一样没办法了,我直接打印一下 GC 的日志,看下日志里面显示什么,这个参数就上场了,他可以输出 GC 详细的分区分析,我们再次运行刚才的两个例子如下。按照书中或者是网上的文章发现,设置这个参数以后默认就是如下两个组合,新生代用。,可以直接使用如下命令验证,我用的不是。

csdn_life18的博客 1697

使用VNA(Vector Network Analyzer)对S参数进行去嵌(一)

传统上,RF和微波组件被设计成具有同轴接口的封装。通过连接一系列这些单独的同轴设备,可以容易地制造复杂的系统。使用使用类似同轴接口的标准测试设备可以很容易地测量这些部件和系统的性能。然而,现代系统需要更高水平的组件集成、更低的功耗和更低的制造成本。射频组件正在迅速从使用昂贵同轴接口的设计转向使用印刷电路板和表面贴装技术(SMT)的设计。传统的同轴接口甚至可以从最终产品中取消。这就给设计者留下了用需要同轴接口的测试设备测量这些射频和微波组件性能的问题。解决方案是使用连接同轴和非同轴传输线的测试夹具。

小孟同学的博客 1万+
上一篇: 几种Portal技术的比较与评述
下一篇: 在Eclipse3.0.x配置基于STRUTS的WEB开发环境(相关下载)
java169
博客等级 码龄19年 27粉丝 2568原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值