问题描述
1.java的对象不一定会被gc回收。问下不用new关键字创造的特殊对象有哪几种?Strings="ss";算吗?字符串池不在gc的回收范围吗?2.finalized()并不是c++的析构方法?为什么调用System.gc()不一定要调用finalized()?在这里对象的终结条件怎么理解?怎么自己重写finalized()?将将回收的对象的引用置为null?将流引用的文件关闭?3.为啥说java的gc不能完全代替c的析构?能探讨下gc的两种工作“暂停-复制"和"标记-清理"的模式吗?堆内碎片多gc就会切换“暂停-复制",程序稳定时调用"标记-清理"说说吧,这是我看thinkinjava的疑惑
解决方案
解决方案二:
顶一下,坐沙发等大神。
解决方案三:
垃圾回收主要指堆和方法区的内存回收,由于方法区垃圾回收比较苛刻,所以字符串常量池从JDK7后由方法区移出,但不论在哪它都在gc的范围之内,finalized方法算是个奇葩,任何一个对象,在被gc之前都会且只会被调用一次finalized,但并不保证被完整的执行,没有任何理由需要重写finalized方法,也就是这个方法对于程序员而言一点用处都没。将引用设置为null只是将对象从GcRoots上断开,等待下次垃圾回收。不同的垃圾收集器针对自己内存区域的特定采用不同的收集算法,“标记-复制”算法简单,执行效率高但浪费内存,但由于其高效性,堆新生代中一直使用的这个算法,“标记-清理"算法复杂,需要更复杂的收集器来支持。
解决方案四:
楼上大神回答的不错。你可以看下应该能比较详细的回答你的第三个问题。
解决方案五:
1.java的对象不一定会被gc回收。问下不用new关键字创造的特殊对象有哪几种?Strings="ss";算吗?字符串池不在gc的回收范围吗?java的对象不一定会被gc回收。扯,如果有对象不能被gc,这叫做“内存泄露”,迟早内存会爆。不用new关键字创造的特殊对象有哪几种?创建的对象就是对象,无所谓特殊。不用new也可以创建,反射可以创建对象Strings="ss";算吗?这里的"ss"存在于常量池里,是常量池里的一块内存,不能算做是对象。不过实践中不用分的那么清楚,只要知道怎么用s这个变量去操作字符串就行了字符串池不在gc的回收范围吗?不对,刚才解释了预定义的常量字符串在常量池里,常量池是属于class的,class是在方法区的。所以你所说的“字符串池”是在方法区里,也是在gc回收范围之内的。有兴趣可以去google:classloadunload2.finalized()并不是c++的析构方法?为什么调用System.gc()不一定要调用finalized()?在这里对象的终结条件怎么理解?怎么自己重写finalized()?将将回收的对象的引用置为null?将流引用的文件关闭?finalized()并不是c++的析构方法?正确。java里的finalized方法和c++里的语义不一样为什么调用System.gc()不一定要调用finalized()?finalized只会被调用一次,如果调用过一次之后这个对象还没有被回收,等到它真正被回收的时候,finalized却不会再次被调用了。在这里对象的终结条件怎么理解?怎么自己重写finalized()?不需要重写。写了这么多年java,从来没有重写过。因为上面解释的原因,finalized并不能当作c++里的内存释放一样来使用,并且不保证一定在gc的时候被调用,所以java里这是一个不靠谱的东西,实践中是从来不用的将将回收的对象的引用置为null?将流引用的文件关闭?这个操作是必须的,原因不用我来说了吧。一般放在finally里做,保证打开的资源一定被释放3.为啥说java的gc不能完全代替c的析构?能探讨下gc的两种工作“暂停-复制"和"标记-清理"的模式吗?堆内碎片多gc就会切换“暂停-复制",程序稳定时调用"标记-清理"说说吧,这是我看thinkinjava的疑惑为啥说java的gc不能完全代替c的析构?个人认为差别不大。java里是JVM来帮你做gc的工作,析构是自己手动释放,想什么时候释放什么时候释放,我想区别可能在这里吧。从效果上来看,我觉得差不多。毕竟都是做的内存释放的工作,没听说过java在内存释放上有问题导致用不了能探讨下gc的两种工作“暂停-复制"和"标记-清理"的模式吗?这种网上资料太多了,不赘述,自己去搜索。笼统的来说,就是两种不同的思路算法堆内碎片多gc就会切换“暂停-复制",程序稳定时调用"标记-清理"复制算法会把被小对象分割开的内存碎片放到一起,让内存使用更有效率。
解决方案六:
多谢啊,明白了不少啊
解决方案七:
gc回收内存是有一定的算法,如果你想创建一个gc回收不了的java对象,是完全可以的。但这种对象具有很大的危险性,有可能导致内存溢出。
解决方案八:
4楼给你回复的差不多!补充下:java对象不能被gc回收掉那就是内存泄露。java不一定通过new,别忘了有反射。但一个类初始化的需要在4种字节码指令下才会触发(newgetstaticputstaticinvokestatic)。Strings="s"也是种。难道你忘了所有对象的父类都是Object?常量池在方法区。方法区同样属于堆,自然而然在gc内。方法接口字段都一样,只是他们有自己回收的条件。暂停-复制?应该叫做标记-复制,也就是先标记出需要清除的对象,然后在复制到堆某一端,这种方式可以解决碎片问题,但是它比较占用堆空间,所以就出现了标记-整理-清楚先标记把要清除的对象全部移动到一起然后在清除,为什么有暂停一说,就好比你妈给你打扫房间,你是不是停下来产生垃圾行为,让你妈清理?但是不暂停的话,你妈给你打扫一次房间,你一边丢,那产生的新垃圾你妈不停的给你打扫还是等待下一次打扫时在打扫呢?
解决方案九:
来看一下大神们的回复。。
解决方案十:
C/C++的析构处理,给出了程序统一释放内存、解除I/O操作(数据库连接、网络连接、文件操作等)的时机但是具体的释放和解除操作都得程序员自己手动编写代码来完成,包括先释放/解除谁,后释放/解除谁这些细微的顺序如果搞错了,都有可能导致整个程序崩溃不过这符合C语言的哲学:“程序员应该知道自己在做什么”Java的GC,在JVM认为合适的时机下,自动的帮助程序员释放内存,主要目的是为了减少内存泄露造成的不易察觉的Bug但是,仅仅依靠GC,并不能解除如:数据库连接、网络连接、文件操作等I/O操作需要自己在合适的时机下(一般为finally代码块中),手动调用close方法具体的讨论可以参考下面的帖子http://bbs.csdn.net/topics/390812239Q:为啥说Java的GC不能完全代替C/C++的析构?A:书写良好的C/C++的析构约等于Java的GC(自动释放内存)+finally中的close(手动解除I/O操作)