各位大神有空的来探讨下java的垃圾回收机制吧 java对象string工作c++ 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 垃圾回收主要指堆和方法区的内存回收,由于方法区垃圾回收比较苛刻, 所以字符串常量池从JDK7后由方法区移出,但不论在哪它都在gc的范围之内,finalized方法算是个奇葩,任何一个对象,在被gc之前都会且只会被调用一次finalized,但并不保证被完整的执行,没有任何理由需要重写finalized方法,也就是这个方法对于程序员而言一点用处都没。将引用设置为null只是将对象从Gc Roots上断开,等待下次垃圾回收。不同的垃圾收集器针对自己内存区域的特定采用不同的收集算法,“标记-复制”算法简单,执行效率高但浪费内存,但由于其高效性,堆新生代中一直使用的这个算法,“标记-清理"算法复杂,需要更复杂的收集器来支持。 楼上大神回答的不错。你可以看下http://blog.csdn.net/u014496722/article/details/27639171应该能比较详细的回答你的第三个问题。 1.java的对象不一定会被gc回收。 问下 不用new关键字创造的特殊对象 有哪几种? String s ="ss";算吗? 字符串池不在gc的回收范围吗? java的对象不一定会被gc回收。 扯,如果有对象不能被gc,这叫做“内存泄露”,迟早内存会爆。不用new关键字创造的特殊对象 有哪几种?创建的对象就是对象,无所谓特殊。不用new也可以创建,反射可以创建对象String s ="ss";算吗?这里的"ss"存在于常量池里,是常量池里的一块内存,不能算做是对象。不过实践中不用分的那么清楚,只要知道怎么用s这个变量去操作字符串就行了 字符串池不在gc的回收范围吗?不对,刚才解释了预定义的常量字符串在常量池里,常量池是属于class的,class是在方法区的。所以你所说的“字符串池”是在方法区里,也是在gc回收范围之内的。有兴趣可以去google:class load unload2.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就会切换“暂停-复制",程序稳定时调用"标记-清理" 说说吧,这是我看think in java的疑惑为啥说java的gc不能完全代替 c的析构?个人认为差别不大。java里是JVM来帮你做gc的工作,析构是自己手动释放,想什么时候释放什么时候释放,我想区别可能在这里吧。从效果上来看,我觉得差不多。毕竟都是做的内存释放的工作,没听说过java在内存释放上有问题导致用不了能探讨下 gc的两种工作 “暂停-复制" 和 "标记-清理"的模式吗?这种网上资料太多了,不赘述,自己去搜索。笼统的来说,就是两种不同的思路算法 堆内碎片多gc就会切换“暂停-复制",程序稳定时调用"标记-清理" 复制算法会把被小对象分割开的内存碎片放到一起,让内存使用更有效率。 gc回收内存是有一定的算法,如果你想创建一个gc回收不了的java对象,是完全可以的。但这种对象具有很大的危险性,有可能导致内存溢出。 4楼 给你回复的 差不多!补充下:java 对象不能被gc 回收掉 那就是 内存泄露。java 不一定通过new ,别忘了 有反射。但一个类初始化的 需要在4种 字节码指令下才会触发(new getstatic putstatic invokestatic)。String s ="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操作) 救救小弟,请教一个JAVA中随机事件按概率发生的问题 多态的问题,请指点一下?(分用光了抱歉) 一个内部类问题? oracle的jvm与我安装的jdk冲突,导致tomcat不能启动 请问如何很快的学好JAVA? 请教这条sql语句有错吗?? HashMap为什么要采用数组和链表来实现? 关于JTable 哪位介绍一些信息发布方面的开源项目 请问:如何在Jbuilder4.0中实现树状列? struts上传文件抛Read timed out异常 自己写的java web框架,大家支持一下
不同的垃圾收集器针对自己内存区域的特定采用不同的收集算法,“标记-复制”算法简单,执行效率高但浪费内存,但由于其高效性,堆新生代中一直使用的这个算法,“标记-清理"算法复杂,需要更复杂的收集器来支持。
java的对象不一定会被gc回收。
扯,如果有对象不能被gc,这叫做“内存泄露”,迟早内存会爆。
不用new关键字创造的特殊对象 有哪几种?
创建的对象就是对象,无所谓特殊。不用new也可以创建,反射可以创建对象
String s ="ss";算吗?
这里的"ss"存在于常量池里,是常量池里的一块内存,不能算做是对象。不过实践中不用分的那么清楚,只要知道怎么用s这个变量去操作字符串就行了
字符串池不在gc的回收范围吗?
不对,刚才解释了预定义的常量字符串在常量池里,常量池是属于class的,class是在方法区的。所以你所说的“字符串池”是在方法区里,也是在gc回收范围之内的。有兴趣可以去google:class load unload2.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就会切换“暂停-复制",程序稳定时调用"标记-清理" 说说吧,这是我看think in java的疑惑
为啥说java的gc不能完全代替 c的析构?
个人认为差别不大。java里是JVM来帮你做gc的工作,析构是自己手动释放,想什么时候释放什么时候释放,我想区别可能在这里吧。从效果上来看,我觉得差不多。毕竟都是做的内存释放的工作,没听说过java在内存释放上有问题导致用不了
能探讨下 gc的两种工作 “暂停-复制" 和 "标记-清理"的模式吗?
这种网上资料太多了,不赘述,自己去搜索。笼统的来说,就是两种不同的思路算法
堆内碎片多gc就会切换“暂停-复制",程序稳定时调用"标记-清理"
复制算法会把被小对象分割开的内存碎片放到一起,让内存使用更有效率。
但是具体的释放和解除操作都得程序员自己手动编写代码来完成,
包括先释放/解除谁,后释放/解除谁这些细微的顺序如果搞错了,都有可能导致整个程序崩溃
不过这符合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操作)