Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java工作面试。有多少对象符合垃圾收集的条件?_Java_Reference_Garbage Collection - Fatal编程技术网

Java工作面试。有多少对象符合垃圾收集的条件?

Java工作面试。有多少对象符合垃圾收集的条件?,java,reference,garbage-collection,Java,Reference,Garbage Collection,下面是一个典型的Java求职面试问题。System.gc()将垃圾收集多少对象 我将在代码中使用以下名称: a1包含对a1的引用 a2包含对a2的引用 mas包含对mas的引用,以及 list包含对list的引用 使用过的类。 package com.mock; public class GCTest { static class A { private String myName; public A(String myName) {

下面是一个典型的Java求职面试问题。
System.gc()将垃圾收集多少对象

我将在代码中使用以下名称:

  • a1
    包含对
    a1
    的引用
  • a2
    包含对
    a2
    的引用
  • mas
    包含对
    mas
    的引用,以及
  • list
    包含对
    list
    的引用
使用过的类。

package com.mock;

public class GCTest {

    static class A {

        private String myName;

        public A(String myName) {
            this.myName = myName;
        }
    }
}
package com.mock;

import com.mock.GCTest.A;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        A a1 = new A("a1"); // A ref to A1. 1 ref in all.
        A a2 = new A("a2"); // A ref to A2. 2 refs in all.
        ArrayList<A> list = new ArrayList<A>(); // A ref to the empty ArrayList. 3 refs in all.
        list.add(a1); // The list has a1 holding a ref to A1 
        A[] mas = new A[2]; // A ref to an array; it has nulls in it. 4 refs in all.
        mas[0] = a2; // Now mas holds the ref to A2.
        a2 = a1; // a2 holds the ref to A1 
        clear(mas); // Nothing changed because methods deals with copies of parameters rather than with parameters themselves. 
        a1 = null; // a1 no longer holds the ref to A1
        a2 = null; // a2 no longer holds the ref to A1
        System.gc(); // Nothing should be garbage collected
    }

    private static void clear(A[] mas) {
        mas = null;
    }

}
用法。

package com.mock;

public class GCTest {

    static class A {

        private String myName;

        public A(String myName) {
            this.myName = myName;
        }
    }
}
package com.mock;

import com.mock.GCTest.A;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        A a1 = new A("a1"); // A ref to A1. 1 ref in all.
        A a2 = new A("a2"); // A ref to A2. 2 refs in all.
        ArrayList<A> list = new ArrayList<A>(); // A ref to the empty ArrayList. 3 refs in all.
        list.add(a1); // The list has a1 holding a ref to A1 
        A[] mas = new A[2]; // A ref to an array; it has nulls in it. 4 refs in all.
        mas[0] = a2; // Now mas holds the ref to A2.
        a2 = a1; // a2 holds the ref to A1 
        clear(mas); // Nothing changed because methods deals with copies of parameters rather than with parameters themselves. 
        a1 = null; // a1 no longer holds the ref to A1
        a2 = null; // a2 no longer holds the ref to A1
        System.gc(); // Nothing should be garbage collected
    }

    private static void clear(A[] mas) {
        mas = null;
    }

}
package.com.mock;
导入com.mock.GCTest.A;
导入java.util.ArrayList;
公共班机{
公共静态void main(字符串[]args){
a1=新的A(“a1”);//一个对a1.1的引用。
a2=新的A(“a2”);//A到a2的引用。总共2个引用。
ArrayList=new ArrayList();//对空ArrayList的引用。总共有3个引用。
list.add(a1);//列表中的a1包含对a1的引用
A[]mas=new A[2];//数组的引用;数组中有空值。总共有4个引用。
mas[0]=a2;//现在mas持有对a2的引用。
a2=a1;//a2保存对a1的引用
clear(mas);//没有任何更改,因为方法处理的是参数的副本,而不是参数本身。
a1=null;//a1不再保存对a1的引用
a2=null;//a2不再保存A1的引用
System.gc();//不应垃圾收集任何内容
}
专用静态无效清除(A[]毫安时){
mas=null;
}
}

这很可能是个棘手的问题

System.gc()
的功能取决于底层垃圾收集器

gc

public static void gc()

Runs the garbage collector.

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

The call System.gc() is effectively equivalent to the call:

     Runtime.getRuntime().gc()


See Also:
    Runtime.gc()
你知道的是:

  • 0到“程序中的对象数”
    Object
    s之间的对象将被垃圾收集
  • 很有可能在0到“应该被垃圾收集的对象数”之间
  • 相对而言,它很可能会进行垃圾收集,即“应该进行垃圾收集的对象的数量”

我的答案是0,因为
list
mas
都有引用
A1
(list)和
A2
(mas)的元素

为了简化我的答案,我创建了三个图表。矩形对应于内存中的块;圆对应于物体。灰色箭头对应于不再存在的引用

在a1=a2之前。

package com.mock;

public class GCTest {

    static class A {

        private String myName;

        public A(String myName) {
            this.myName = myName;
        }
    }
}
package com.mock;

import com.mock.GCTest.A;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        A a1 = new A("a1"); // A ref to A1. 1 ref in all.
        A a2 = new A("a2"); // A ref to A2. 2 refs in all.
        ArrayList<A> list = new ArrayList<A>(); // A ref to the empty ArrayList. 3 refs in all.
        list.add(a1); // The list has a1 holding a ref to A1 
        A[] mas = new A[2]; // A ref to an array; it has nulls in it. 4 refs in all.
        mas[0] = a2; // Now mas holds the ref to A2.
        a2 = a1; // a2 holds the ref to A1 
        clear(mas); // Nothing changed because methods deals with copies of parameters rather than with parameters themselves. 
        a1 = null; // a1 no longer holds the ref to A1
        a2 = null; // a2 no longer holds the ref to A1
        System.gc(); // Nothing should be garbage collected
    }

    private static void clear(A[] mas) {
        mas = null;
    }

}

在a1=a2之后。

package com.mock;

public class GCTest {

    static class A {

        private String myName;

        public A(String myName) {
            this.myName = myName;
        }
    }
}
package com.mock;

import com.mock.GCTest.A;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        A a1 = new A("a1"); // A ref to A1. 1 ref in all.
        A a2 = new A("a2"); // A ref to A2. 2 refs in all.
        ArrayList<A> list = new ArrayList<A>(); // A ref to the empty ArrayList. 3 refs in all.
        list.add(a1); // The list has a1 holding a ref to A1 
        A[] mas = new A[2]; // A ref to an array; it has nulls in it. 4 refs in all.
        mas[0] = a2; // Now mas holds the ref to A2.
        a2 = a1; // a2 holds the ref to A1 
        clear(mas); // Nothing changed because methods deals with copies of parameters rather than with parameters themselves. 
        a1 = null; // a1 no longer holds the ref to A1
        a2 = null; // a2 no longer holds the ref to A1
        System.gc(); // Nothing should be garbage collected
    }

    private static void clear(A[] mas) {
        mas = null;
    }

}

a1和a2都不包含引用

我可以覆盖类
A
finilize()
,以查看哪些符合石笼收集的条件

@Override
protected void finalize() throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("finalize: " + myName);
    super.finalize();
}
虽然我在测试代码时看到了日志,但是不能100%保证调用后内存是干净的

运行垃圾收集器

gc

public static void gc()

Runs the garbage collector.

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

The call System.gc() is effectively equivalent to the call:

     Runtime.getRuntime().gc()


See Also:
    Runtime.gc()
调用gc方法意味着Java虚拟机需要 努力回收未使用的对象,以使内存 它们目前可用于快速重用。当控件返回时 从方法调用来看,Java虚拟机已经尽了最大的努力 从所有丢弃的对象中回收空间


当你已经有了答案,你应该把它贴出来。因此,我建议您自己创建一个答案,并移动问题的第二部分。如果你是对的,你会得到一些选票。当人们因为错误而呼叫它时,你仍然可以删除它。“技巧性问题”的答案是:未知,因为调用
System.gc()
实际上不能保证它返回时执行了完整的垃圾收集循环。为什么
list
会被垃圾收集?最后仍然是一个空的
列表
,因此对垃圾收集无效。在这类问题中,绝不是“应该垃圾收集多少对象”或“将垃圾收集多少对象”,而是有多少对象符合垃圾收集条件。@eis不一定。面试官总是有可能不知道他在说什么。好吧,让我重新表述一下我原来的问题。
System.gc()
应该垃圾收集多少个对象?但是,在System.gc()调用之后,不会使用mas和list,因此智能编译器或JIT可能会意识到他已经可以垃圾收集所有对象了。不知道实际的实现是什么,但是我不能保证在调用之后对象仍然在内存中。如果你考虑一个“智能编译器或JIT”,甚至不需要创建对象。