Java 垃圾收集是否保证程序不会耗尽内存?
我听说java最优雅的特性是垃圾收集Java 垃圾收集是否保证程序不会耗尽内存?,java,Java,我听说java最优雅的特性是垃圾收集 我想知道它能保证程序不会耗尽内存吗?不,它不能保证这一点。程序员完全有可能错误地创建永远不会超出范围的对象,从而消耗越来越多的内存,直到所有堆耗尽 程序员有责任确保不再使用的对象不再被应用程序引用。这样,垃圾收集器就可以完成其工作并回收这些对象使用的内存 示例 public class Main { public static void main(String[] main) { List<String> l = new Linked
我想知道它能保证程序不会耗尽内存吗?不,它不能保证这一点。程序员完全有可能错误地创建永远不会超出范围的对象,从而消耗越来越多的内存,直到所有堆耗尽 程序员有责任确保不再使用的对象不再被应用程序引用。这样,垃圾收集器就可以完成其工作并回收这些对象使用的内存 示例
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();
}
该列表将无限期地增长,直到您的内存耗尽。要回答您的问题,
否
。垃圾收集不能保证程序不会耗尽内存
- 考虑一下你们不想看到的对象 使用更多的东西就像垃圾
- 对这些对象的引用将被删除 就像你家里有垃圾一样 房子
- 垃圾收集就像你的 收集垃圾的城镇垃圾车 垃圾
- 如果你不释放那些 参考资料,这就像不采取行动 把垃圾扔出去,很快你的房子就会 垃圾堆积如山 垃圾车的家伙不会带出去的 你家的垃圾
- 如果对象没有引用, 它有资格成为垃圾桶 收藏
- 对象是在堆上分配的
- 垃圾收集器时不时地运行 删除未引用对象的时间 从堆里
- 如果继续在上创建更多对象
堆积而不释放你的意志
最终从内存错误中获取
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();
}
}