垃圾收集的几个问题

squander 2001-05-10 06:02:00
如下的程序有些不懂。
import java.util.*;
class Chair {
static boolean gcrun = false;//the flag wheather garbage machine start run
static boolean f = false;//the flag tell main function to stop create object
static int created = 0;//the flag wheather object contruct
static int finalized = 0;//the flag weather object finalized
int i;//the NO of Object
Chair() {
i = ++created;
if(created == 47)
System.out.println("Created 47");
}
public void finalize() {
if(!gcrun) {
// The first time finalize() is called:
gcrun = true;
System.out.println(
"Beginning to finalize after " +
created + " Chairs have been created");
}
if(i == 47) {
System.out.println(
"Finalizing Chair #47, " +
"Setting flag to stop Chair creation");
f = true;
}
finalized++;
if(finalized >= created)
System.out.println(
"All " + finalized + " finalized");
}
}

public class Garbage {
public static void main(String[] args) {
// As long as the flag hasn't been set,
// make Chairs and Strings:
while(!Chair.f) {
new Chair();
new String("To take up space");
}
System.out.println(
"After all Chairs have been created:\n" +
"total created = " + Chair.created +
", total finalized = " + Chair.finalized);
// Optional arguments force garbage
// collection & finalization:
if(args.length > 0) {
if(args[0].equals("gc") ||
args[0].equals("all")) {
System.out.println("gc():");
System.gc();
}
if(args[0].equals("finalize") ||
args[0].equals("all")) {
System.out.println("runFinalization():");
System.runFinalization();
}
}
System.out.println("bye!");
}
} ///:~
当程序java Garbage执行时,输出结果为:
Created:47
Beginning to finalize after 4893 Chairs have been created
Finalizing Char #47,Setting flag to stop Chair creation
After all Chairs have been created:
total created=4894,total finalized=4892
bye!
对这个程序,我有以下的理解:
1、垃圾收集器的运行不可知、不可控制。可能在内存分配有可能到了一个很大值时,或可能内存分配出错时,
垃圾收集器就会投入运行。
2、垃圾收集器启动以后,好像所有的内存都会回收,这就有一个问题
垃圾收集器如果在程序即将结束时工作,那么程序在整个运行过程如果有大量的废内存存在,岂不是很影响程序的效率。
另一个问题,当程序占用内存很大时,就有可能就引发了垃圾收集器的运行,如果垃圾收集将所有的内存都回收的话,
那岂不是整个程序都会崩溃。
3、是否只有调用了gc()以后,内存才能令清空。那么岂不是在每个程序结束的时候,都应该gc(),否则不一样会有内存
泄露。

以上几点,还请大家指教。
...全文
102 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dureek 2001-05-14
  • 打赏
  • 举报
回复
Hi JavaIsKing =)
java(目前)只是不适合做OS而已, 你可以去 http://www.jos.org/ 看看^^
我觉得他们用java做os最大的贡献不是做出的os, 而是能帮助发现java深层的问题——而这恰恰通常是做应用的难以发现的, 比如他们提交的JSR, 相信对java今后的发展都是非常有帮助的 ...
squander 2001-05-14
  • 打赏
  • 举报
回复
如果将一个句柄设为了NULL,则垃圾收集器就会处理他们。
JavaIsKing 2001-05-11
  • 打赏
  • 举报
回复
何时进行GC,由不同的JVM和当时的情况决定,如系统忙于响应,或有其他关键线程,都将影响gc,
无人能准确控制gc,just eligible.
因此java的GC无法保证防止内存溢出,我想因此java无法作出os, unlike c++.
squander 2001-05-11
  • 打赏
  • 举报
回复
感谢你的回答
我是学C++出身的,我对内存还是有一些问题,举个例子,程序中有一个数组,每个数组元素都分配了一个对象,这个数组在程序的后续执行过程中,不再使用了,在程序结束前,垃圾收集器并不能适时的回收他们,这样程序效率不是很低吗?
2、程序在结束时,垃圾收集器就应该投入运行吧,这时就应该回收程序中的所有内存了吧。
3、在JVM中运行一段程序后,是否总有些废内存占据着空间八?
JavaIsKing 2001-05-11
  • 打赏
  • 举报
回复
Java 定义finlized(),是因为由c而来,实际编程无需过多考虑。另外:gc仅针对对象,而非
primitive type变量,因为对象存储在heap中,需要系统线程进行清理,开销较大。而primitive type变量存在stack中,清理开销小,只需push,pop。基于此种考虑,java象C+
+一样使用混合类型,而非象smalltalk的纯对象方式。c#则采用了动态方式。
另:因为在多线程,无法控制GC,system.gc()只是建议。finalized()只能被系统调用一次,但程序可用调用,但与GC无关。
举例:
public MyGC{
public static void main(String[] args){
String s1="123";
String s2="456";
s1=s2; // String object "123" is eligible for GC , as no reference point to it

}

}
luodi 2001-05-11
  • 打赏
  • 举报
回复
是System.runFinalizersOnExit(boolean value),注意大小写,注意参数是true/false,而且这个方法不建议使用了。
另外,Java中为什么有这个函数,真是不是很清楚,也许是以后JVM可以确保释放前调用吧,现阶段还是取决于具体的JVM实现了。
squander 2001-05-11
  • 打赏
  • 举报
回复
非常感谢你的回答,作为一个初学JAVA的我,对GC有了更深的理解,但我对JAVA中的finalize()这个函数还不是很清楚。
我的理解是这样的:
finalize()这个函数基本上是没什么用的,现在的JAVA并不能保障所有对象的析构时会一定调用此函数,包括System.runFinalization()也是这样,要确保对象析构时,不仅要释放内存,还要做其他工作(如:关闭文件),必须自己编函数,并且保证用finaly子句调用他。
我的理解对吗?
既然如此,为什么JAVA还要有这个函数。
另一个问题:
system.runFinalizersOnExit()这个函数怎么我在JBUILDER3.5的help上没找到。这个函数是否不用了,如果用的话,这个函数如何理解。
以上几个问题,又得麻烦大家了。
我感觉CSDN真的是太好了。
luodi 2001-05-11
  • 打赏
  • 举报
回复
GC不会收回所有的内存,只会收回那些没有被引用的内存!所以是不会使整个程序崩溃的。
另外是否所有的未被引用的内存都会回收,这一点也会取决于具体的JVM的实现,无法确保。而且调用GC的开销是巨大的,绝对不推荐每个程序结束时调用,一般来说还是应该信任JVM自身的调度,非万不得已或确有需要时不需要人为调用。
lmy2000 2001-05-11
  • 打赏
  • 举报
回复
“何时进行GC,由不同的JVM和当时的情况决定,如系统忙于响应,或有其他关键线程,都将影响gc” 深表赞同!
“我想因此java无法作出os, unlike c++. ”只怕未必。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧