㈠ java中的垃圾回收是什么意思
垃圾回收就是gc(gabage collection)。
java比c++的优点就是多了垃圾回收机制,程序员不用去关心垃圾的回收,系统会自动调用去回收内存。
一般我们想回收的时候只需要调用system.gc方法就可以了。系统会自己去调用destroy方法和其他的回收方法释放内存,节省内存空间。
㈡ 在面试时怎么回答java垃圾回收机制
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态内回收无任何引用的对容象占据的内存空间。
需要注意的是:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,很多人来我公司面试时,我都会问这个问题的,70%以上的人回答的含义是回收对象,实际上这是不正确的。
System.gc()
Runtime.getRuntime().gc()
上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。
㈢ 垃圾回收的几种方式
此外,一些算法可以以 增量方式完成它们的工作(不需要一次收集整个堆,使得收集暂停时间更短),一些算法可以在用户程序运行时运行(并发收集)。
其他算法则必须在用户程序暂停时一次进行整个收集(即所谓的 stop-the-world收集器)。最后,还有混合型的收集器,如1.2 和以后版本的 JDK 使用的分代收集器,它对堆的不同区域使用不同的收集算法。
不同的垃圾收集实现使用不同的策略来识别和收回不可到达的对象,它们与用户程序和调度器以不同的方式互动。不同类型的应用程序对于垃圾收集有不同的要求 ―― 实时应用程序会将要求收集暂停的持续时间短并且有限制,而企业应用程序可能允许更长时间和可预测性更低的暂停以获得更高的吞吐能力。
有几种垃圾收集的基本策略:引用计数、标记-清除、标记-整理 (mark-compact) 和复制。此外,一些算法可以以 增量 方式完成它们的工作(不需要一次收集整个堆,使得收集暂停时间更短),一些算法可以在用户程序运行时运行( 并发收集)。
其他算法则必须在用户程序暂停时一次进行整个收集(即所谓的 stop-the-world收集器)。最后,还有混合型的收集器,如1.2 和以后版本的 JDK 使用的分代收集器,它对堆的不同区域使用不同的收集算法。
在对垃圾收集算法进行评价时,我们可能要考虑以下所有标准:*暂停时间
。收集器是否停止所有工作来进行垃圾收集?要停止多长时间?暂停是否有时间限制?*暂停的可预测性
。垃圾收集暂停是否规划为在用户程序方便而不是垃圾收集器方便的时间发生?*CPU 占用
。总的可用 CPU 时间用在垃圾收集上的百分比是多少?*内存大小
。许多垃圾收集算法需要将堆分割成独立的内存空间,其中一些空间在某些时刻对用户程序是不可访问的。这意味着堆的实际大小可能比用户程序的最大堆驻留空间要大几倍。*虚拟内存交互
。在具有有限物理内存的系统上,一个完整的垃圾收集在垃圾收集过程中可能会错误地将非常驻页面放到内存中来进行检查。因为页面错误的成本很高,所以垃圾收集器正确管理引用的区域性 (locality) 是很必要的。*缓存交互
。即使在整个堆可以放到主内存中的系统上 ―― 实际上几乎所有 Java 应用程序都可以做到这一点,垃圾收集也常常会有将用户程序使用的数据冲出缓存的效果,从而影响用户程序的性能。*对程序区域性的影响
。虽然一些人认为垃圾收集器的工作只是收回不可到达的内存,但是其他人认为垃圾收集器还应该尽量改进用户程序的引用区域性。整理收集器和复制收集器在收集过程中重新安排对象,这有可能改进区域性。*编译器和运行时影响
基本算法引用计数最直观的垃圾收集策略是引用计数。引用计数很简单,但是需要编译器的重要配合,并且增加了赋值 函数 (mutator)的开销(这个术语是针对用户程序的,是从垃圾收集器的角度来看的)。每一个对象都有一个关联的引用计数 ―― 对该对象的活跃引用的数量。如果对象的引用计数是零,那么它就是垃圾(用户程序不可到达它),并可以回收。每次修改指针引用时(比如通过赋值语句),或者当引用超出范围时,编译器必须生成代码以更新引用的对象的引用计数。如果对象的引用计数变为零,那么运行时就可以立即收回这个块(并且减少被回收的块所引用的所有块的引用计数),或者将它放到迟延收集队列中。
引用计数很简单,很适用于增量收集,收集过程一般会得到好的引用区域性,但是出于几个理由,它很少在生产垃圾收集器中使用,如它不能回收不可到达的循环结构(彼此直接或者间接引用的几个对象,如循环链接的列表或者包含指向父节点的反向指针的树)。
跟踪收集器JDK 中的标准垃圾收集器都没有使用引用计数,相反,它们都使用某种形式的跟踪收集器 (tracing collector)。跟踪收集器停止所有工作(尽管不需要在收集的整个过程中都这样)并开始跟踪对象,从根集开始沿着引用跟踪,直到检查了所有可到达的对象。可以在程序注册表中、每一个线程堆栈中的(基于堆栈的)局部变量中以及静态变量中找到根。
标记-清除收集器
最早由 Lisp 的发明人 John McCarthy 于 1960 年提出的最基本的跟踪收集器形式是 标记―清除收集器,它停止所有工作,收集器从根开始访问每一个活跃的节点,标记它所访问的每一个节点。走过所有引用后,收集就完成了,然后就对堆进行清除(即对堆中的每一个对象进行检查),所有没有标记的对象都作为垃圾回收并返回空闲列表。
标记-清除实现起来很简单,可以容易地回收循环的结构,并且不像引用计数那样增加编译器或者赋值函数的负担。但是它也有不足 ―― 收集暂停可能会很长,在清除阶段整个堆都是可访问的,这对于可能有页面交换的堆的虚拟内存系统有非常负面的性能影响。
标记-清除的最大问题是,每一个活跃的(即已分配的)对象,不管是不是可到达的,在清除阶段都是可以访问的。因为很多对象都可能成为垃圾,这意思着收集器花费大量精力去检查并处理垃圾。标记-清除收集器还容易使堆产生碎片,这会产生区域性问题并可以造成分配失败,即使看来有足够的自由内存可用。
复制收集器在另一种形式的跟踪收集器 ―― 复制收集器中,堆被分成两个大小相等的半空间,其中一个包含活跃的数据,另一个未使用。当活跃的空间占满以后,程序就会停止,活跃的对象被从活跃的空间复制到不活跃的空间中。空间的角色就会转换,原来不活跃的空间成为了新的活跃空间。
堆整理复制收集器有另一个好处,活跃对象集会被整理到堆的底部。这不仅改进了用户程序的引用区域性并消除了堆碎片,而且极大地减少了对象分配的成本 ―― 对象分配变成了在堆顶部的指针上增加指针。不需要维护自由列表或者后备列表,或者使用性能最佳或者第一合适的算法 ―― 分配 N 字节就是在堆顶部指针上加 N 并返回前一个值这么简单
为非垃圾收集语言实现了复杂内存管理方案的开发人员可能会对复制收集器中廉价的内存分配感到吃惊 ―― 就是指针加法这么简单。以前的 JVM 实现没有使用复制收集器 ―― 这可能是对象分配是昂贵的这一想法是如此普遍的原因之一,开发人员仍然下意识地假设分配成本与其他语言(如 C)类似,而事实上在 Java 运行时中可能要廉价得多。不但是分配成本减少了,而且对于在下次收集之前成为垃圾的对象,解除分配的成本为零,因为既不会访问也不会复制垃圾对象。
标记-整理收集器
复制算法的性能很优异,但是它有一个缺点是需要两倍于标记-清除收集器所需要的内存。 标记-整理 算法结合了标记-清除和复制,避免了这个问题,代价是增加了一些收集复杂性。与标记-清除类似,标记-整理是两阶段过程,在标记阶段访问并标记每个活跃对象。然后,复制标记的对象,使所有活跃对象被整理到堆的底部。如果每一次收集时进行彻底的整理,那么得到的堆就类似于复制收集器的结果 ―― 在堆的活跃部分与自由部分有明确的界线,这样分配成本与复制收集器相当。长寿的对象趋向于沉在堆的底部,这样就不会像在复制收集器中那样反复复制它们
那么 JDK 使用了哪种方式进行垃圾收集呢?在某种意义上,使用了所有的方式。早期的 JDK 使用了单线程的标记-清除或者
标记-清除-整理收集器。1.2 及以后的 JDK 使用了混合的方式,称为 分代收集,其中根据对象的年龄将堆分为几个部分,不同的代是用不同的收集算法收集的。分代收集证明是非常高效的,尽管在运行时它需要更多的簿记。
㈣ 垃圾回收的优点和原理
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收
㈤ Java垃圾回收的优点和原理是什么回收机制是怎样的
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的回问题迎刃而解,答它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有”作用域”的概念,只有对象的引用才有”作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
㈥ 快递包装垃圾的增量已占生活垃圾增量的93%!它的存在有何影响
快递包装垃圾的增量已占生活垃圾增量的93%,我们要想出一种共存的方式去处理这些垃圾。快递在我们这个新时代已经是特别多的人都在使用了,但是它制造的垃圾到底怎么样去解决,这是一个重要的问题,当前的话我们可以想出来一个既让这个快递方面不要彻底消失,而且能把这些垃圾快速的处理掉,其实有人提出过,用回收的方式,变废为宝。综上所述,要快递行业和处理快递产生的垃圾,这两者是可以共存的,它的影响也可以通过这样的形式去解决。
㈦ Java垃圾回收怎么理解
垃圾回收是Java语言的一大特性,方便了编程,是以消耗性能为代价的,Java语言对内存的分配管理是通过JVM内部机制决定的。
Java虚拟机中有个称之为垃圾回收器的东西,实际上这个东西也许真正不存在,或者是已经集成到JVM中了,但这无关紧要,仍然可以称为为垃圾回收器。
垃圾回收器的作用是查找和回收(清理)无用的对象。以便让JVM更有效的使用内存。
垃圾回收器的运行时间是不确定的,由JVM决定,在运行时是间歇执行的。虽然可以通过System.gc()来强制回收垃圾,但是这个命令下达后无法保证JVM会立即响应执行,但经验表明,下达命令后,会在短期内执行你的请求。JVM通常会感到内存紧缺时候去执行垃圾回收操作。
垃圾回收过于频繁会导致性能下降,过于稀疏会导致内存紧缺。这个JVM会将其控制到最好,不用程序员担心。但有些程序在短期会吃掉大量内存,而这些恐怖的对象很快使用结束了,这时候也许有必要强制下达一条垃圾回命令,这是很有必要的,以便有更多可用的物理内存。
垃圾回收器仅仅能做的是尽可能保证可用内存的使用效率,让可用内存得到高效的管理。程序员可以影响垃圾回收的执行,但不能控制。
总之,在Java语言中,判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个:
1.给对象赋予了空值null,以下再没有调用过。
2.给对象赋予了新值,既重新分配了内存空间。
㈧ 垃圾回收的简介
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()