是什么决定在垃圾收集器收集实际? 经过一定时间或一定量的内存后,已经使用了它是否会发生? 还是有其他的因素?
Answer 1:
它运行时,它决定了它是时间来运行。 在代的垃圾收集器的一个常见的策略是当代-0存储器的分配失败时,运行集电极。 也就是说,每次分配的内存小块时间(大块通常直接放入“老”一代),系统会检查是否有在GEN-0堆足够的自由空间,如果没有,它运行在GC腾出空间分配成功。 那么旧的数据移动到GEN-1堆,而当空间用完那里,GC运行在一个集合,它升级一直存在时间最长的GEN-2堆,等数据。 所以GC不只是“运行”。 它可能在GEN-0堆只运行(大多数藏品将做到这一点),或者它可以检查每一代人,如果真的有,腾出大量的内存(这是只需要很少相当)。
但这远不是唯一的策略。 同时一个GC在后台运行,清理程序运行时。 有些GC的可能,因为每个内存分配的一部分运行。 增量收集器可能做到这一点,在每个内存分配扫描几个对象。
在垃圾收集器的整个的一点是,它应该只是做它的东西,而不需要来自用户的任何输入。 因此,在一般情况下,你不能,也不应该,预测它什么时候会运行。
我相信太阳JVM获得了代GC不是很久以前(1.6版可能?我没有编写的Java的年龄,所以不知道这一点,但我记得是吃惊不太久以前,当卖点一新版本是一个“代气相色谱法”。这不仅是因为.NET自每日1次。有一)
其他JVM的当然是免费的挑选自己喜欢哪个策略。
编辑:关于Java和代GC以上的部分是不正确的。 请参阅下面的更多细节:
的1.0和1.1的虚拟机所使用的标记扫描收集器,其可以在垃圾回收之后片段堆。 与Java 1.2开始,虚拟机切换到代收集器,它具有更好的碎片整理行为(见Java理论与实践:垃圾收集和性能 )。
所以Java实际上有老少咸宜的代GC。 什么Java 6中的新功能是垃圾,垃圾收集器首先(G1)这是在Java中6u14可用。 据该文章声称在1.6.0_14释放 : 这是不是默认启用。 并行收集器仍然是默认的GC,是普通家庭使用的最有效的GC。 G1,就是要对并发收集器的替代品。 它的设计更可预测,并启用与存储区域设计的快速分配。
Answer 2:
- 这取决于编译程序的方式JIT。
- 从外观我们不能肯定的告诉时候会运行。
- 它遵循一些算法依赖于特定的GC。
- Java虚拟机在客户机与一些虚拟内存在Windows默认的情况下是4GB的运行。 这也取决于在特定时间,自由的虚拟内存。
你可以试试这个小程序来检查GC的行为
public class GCTest {
final int NELEMS = 50000;
void eatMemory() {
int[] intArray = new int[NELEMS];
for (int i=0; i<NELEMS; i++) {
intArray[i] = i;
}
}
public static void main (String[] args) {
GCTest gct = new GCTest();
// Step 1: get a Runtime object
Runtime r = Runtime.getRuntime();
// Step 2: determine the current amount of free memory
long freeMem = r.freeMemory();
System.out.println("free memory before creating array: " + freeMem);
// Step 3: consume some memory
gct.eatMemory();
// Step 4: determine amount of memory left after consumption
freeMem = r.freeMemory();
System.out.println("free memory after creating array: " + freeMem);
// Step 5: run the garbage collector, then check freeMemory
r.gc();
freeMem = r.freeMemory();
System.out.println("free memory after running gc(): " + freeMem);
}
}
可能的输出 - 可能是你的情况不同
free memory before creating array: 4054912
free memory after creating array: 3852496
free memory after running gc(): 4064184
检查此链接http://www.devdaily.com/java/edu/pj/pj010008/
Answer 3:
这取决于什么垃圾收集你实际使用,其如何调整了很多,和很多的投入。
跑步,以HotSpot垃圾收集器以及它如何调整,你可以检查出(随Java中常见的一种)的向下此链接
Answer 4:
这完全取决于实际的JVM和它选择做什么,基本上是伸出你的双手,作为一个程序员。 胡子花白的铁杆专家可能想告诉他们更好地了解了JVM,但凡人这应该被视为黑魔法更好地单独留在家中。
你应该关心你的是,如果它可以与你的程序创建并丢弃对象的速度跟不上。 如果不是同时全球清理时你的整个程序暂停。 这真可谓非常糟糕的响应时间,但很少发生对现代计算机现代JVM的。
如果您想了解在你的程序和时会发生什么,然后调查在最近版本的Java JDK 6的“jvisualvm”工具。 这是偷看里面真的很棒。
Answer 5:
垃圾收集器时,它需要的资源和运行定期,你能告诉时是要花费CPU的收集,使用的好时机影响的System.gc()
您可以通过给你的对象帮助垃圾收集器通过明确归零参考,例如init()
方法是分配资源和cleanup()
明确清理这些资源的方法和归零的引用。 通过调零引用自己可以防止塔伊不必发现有更多的路径到根obects集群垃圾收集器。
Answer 6:
当JVM没有必要的内存空间运行,垃圾收集器将运行并删除不需要的对象和JVM分配内存。
不必要的对象是具有为它没有参考(地址)的对象。
主要有4点对象符合垃圾收集器。
空引用
垃圾收集器可以删除当对象的参考变量分配空的对象,因为它是值
A a = new A(); a = null;
重新分配
当另一个对象被分配到一个对象的引用变量旧引用的对象可以通过垃圾收集器被删除。
A a = new A(100); a =new A(200);
本地范围
如果该对象的块内创建的对象是符合垃圾收集器出来侧块。
if(condition){ A a = new A(); }
隔离
一个对象可以引用另一个对象,但必须有至少一个参考(地址),用于堆叠这些对象变量,否则所有这些对象有资格垃圾收集器。
class A{ A r; A(int i){ //something } } A a1 = new A(100); a1.r = new A(101); a1.rr = new A(102); a1.rrr = a1; a1 = null //all ojects are eligible to garbage collector