Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.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 - Fatal编程技术网

Java 垃圾收集是否保证程序不会耗尽内存?

Java 垃圾收集是否保证程序不会耗尽内存?,java,Java,我听说java最优雅的特性是垃圾收集 我想知道它能保证程序不会耗尽内存吗?不,它不能保证这一点。程序员完全有可能错误地创建永远不会超出范围的对象,从而消耗越来越多的内存,直到所有堆耗尽 程序员有责任确保不再使用的对象不再被应用程序引用。这样,垃圾收集器就可以完成其工作并回收这些对象使用的内存 示例 public class Main { public static void main(String[] main) { List<String> l = new Linked

我听说java最优雅的特性是垃圾收集
我想知道它能保证程序不会耗尽内存吗?

不,它不能保证这一点。程序员完全有可能错误地创建永远不会超出范围的对象,从而消耗越来越多的内存,直到所有堆耗尽

程序员有责任确保不再使用的对象不再被应用程序引用。这样,垃圾收集器就可以完成其工作并回收这些对象使用的内存

示例

public class Main {
  public static void main(String[] main) {
    List<String> l = new LinkedList<String>();

    // Enter infinite loop which will add a String to
    // the list: l on each iteration.
    do {
      l.add(new String("Hello, World"));
    } while(true);
  }
}
公共类主{
公共静态void main(字符串[]main){
列表l=新的LinkedList();
//输入无限循环,该循环将向
//列表:在每次迭代中使用l。
做{
l、 添加(新字符串(“Hello,World”);
}虽然(正确);
}
}

否。如果您构造了大量对象(数百万个)并保留对它们的引用,以便它们不会超出范围(例如,通过将它们添加到ArrayList),则可能会耗尽可寻址内存。

否,仍然有许多方法会耗尽内存。垃圾收集器只能为不再被引用的对象回收内存-这取决于您是否正在引用您不需要的对象,或者对您想要的对象使用软引用,但如果内存紧张,则不介意消失。

否,您总是可能试图分配比可用内存更多的内存


自动垃圾收集仅意味着自动收集垃圾(即未引用的内存)(即回收以供进一步使用)。如果你保留对它的引用,它就不是垃圾,也不会被收集。

绝对不是。即使在像Java这样的垃圾收集语言中,也很容易丢失引用,这意味着对象永远不会被垃圾收集

即使如此,您也可能只是实例化(并保留引用)太多的对象,系统无法处理。

除了从内存中任意删除一项以腾出空间进行新的分配外,如何确保程序不会耗尽内存


现在,如果你真的在(使用)随机选择要驱逐的对象上保留一个引用,该怎么办?你很快就会有不正确的行为。

否。垃圾收集只能防止一种内存泄漏。特别是,当应用程序不再需要内存时,如果不显式释放内存,就会出现这种情况。如果您的应用程序持有对不需要的对象(例如不断增长的列表)的引用,垃圾收集器将无法清理这些对象,并且您的应用程序仍然可能会耗尽内存。

不,一点也不

在没有垃圾收集的语言中,程序员(或他使用的库)负责请求内存,并返回分配的内存进行“回收”。无法保证内存在被请求时可用。但是,如果您从未显式地“回收”,则可能会出现这样的情况:由于没有可用内存,请求被拒绝,但如果内存被回收,则该块可能已为此请求返回

自动垃圾收集意味着系统可以为您回收垃圾。因此,某些请求将使用“可回收”内存进行填充。但是,与非GC语言一样,有些请求无法填充


例如,如果您的系统有1000个可用块,而您同时需要1500个,那么世界上没有GC可以帮助您,因为没有任何东西可以真正用于回收

否,垃圾收集不能保证应用程序不会耗尽内存。它甚至不能保证应用程序在内存可用时不会耗尽内存。如果您接近内存不足或正在分配多个对象,则可能会导致GC抖动,引发内存不足异常。当程序使用了所有物理内存(实际内存和虚拟内存)或程序超过JVM允许的最大内存(请参阅-Xmx)时,程序也可能内存不足。

否。垃圾收集器可帮助您自动释放未使用的内存

其工作方式是,如果无法访问对象引用,则该对象的内存可能会被垃圾回收

例如:

public void test() {
     Object o = new Object();
     // the memory used by  o may be garbage collected after this line
}
但是如果您从不释放对象引用,垃圾收集器将永远不会收集任何内容,并且将抛出OutOfMemoryError

List list = ....
public void test() {
     o = new Object();
     list.add( o ); 
     // the memory used by  o WON'T be garbage collected after this line
     // because its reference is used in the list.
}
如果您多次使用此选项:

 while( true ) {
     test();
 }

该列表将无限期地增长,直到您的内存耗尽。要回答您的问题,
。垃圾收集不能保证程序不会耗尽内存

  • 考虑一下你们不想看到的对象 使用更多的东西就像垃圾
  • 对这些对象的引用将被删除 就像你家里有垃圾一样 房子
  • 垃圾收集就像你的 收集垃圾的城镇垃圾车 垃圾
  • 如果你不释放那些 参考资料,这就像不采取行动 把垃圾扔出去,很快你的房子就会 垃圾堆积如山 垃圾车的家伙不会带出去的 你家的垃圾
未引用的对象将由垃圾收集器自动进行垃圾收集。在java中,对对象的大多数引用都是在您退出方法后自动释放的

对象引用了其他对象,而这些对象又引用了创建整个对象图的其他对象。因此,这样的对象可以被多个对象引用

  • 如果对象没有引用, 它有资格成为垃圾桶 收藏
  • 对象是在堆上分配的
  • 垃圾收集器时不时地运行 删除未引用对象的时间 从堆里
  • 如果继续在上创建更多对象 堆积而不释放你的意志 最终从内存错误中获取
    OutOfMemoryError
垃圾收集示例
public class TestGarbageNoError {

 public static void main(String[] args) {
  String hugeString;
  for (int i = 0; i < Integer.MAX_VALUE; i++) {
   System.out.println("i = " + i);
   hugeString = getHugeString();
   // At each iteration reference variable hugeString 
   // points to new String object. Hence there will be 
   // zero reference to previous string object and will
   // eventually be garbage collected
  }
 }

 public static String getHugeString() {
  StringBuilder sb = new StringBuilder();
  for (int x = 0; x < 5000000; x++) {
   sb.append(x);
  }
  return sb.toString();
 }
}
public class TestGarbageError {

 public static void main(String[] args) {
  Collection<String> memoryLeak = new ArrayList<String>();
  for (int i = 0; i < Integer.MAX_VALUE; i++) {
   System.out.println("i = " + i);
   String hugeString = getHugeString();
   memoryLeak.add(hugeString);
   // At each iteration reference variable hugeString 
   // points to new String object. But all objects are added 
   // to memoryLeak Collection and will always have atleast one 
   // reference, i.e. from memoryLeak object. Hence this string
   // objects will never be garbage collected and program will
   // eventually run out of memory
  }
 }

 public static String getHugeString() {
  StringBuilder sb = new StringBuilder();
  for (int x = 0; x < 5000000; x++) {
   sb.append(x);
  }
  return sb.toString();
 }
}