q*c 发帖数: 9453 | 1 就是为啥有 GC 的语言, 像 c# 和 java, 就没有destructor. 很多的时候
desctructor 那是非常的有用, 特别是非内存的那些文件啊, 外设什么的。
同样的变量生命周期控制, 退栈的时候消灭。
如果有 destructor + GC 岂不是把两样的好处都拿到了吗?这肯定是有原因的。 |
c*m 发帖数: 1114 | 2 C#'s destructor:
1. Automatic way: GC
2. Manual way: Finalize()
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是为啥有 GC 的语言, 像 c# 和 java, 就没有destructor. 很多的时候 : desctructor 那是非常的有用, 特别是非内存的那些文件啊, 外设什么的。 : 同样的变量生命周期控制, 退栈的时候消灭。 : 如果有 destructor + GC 岂不是把两样的好处都拿到了吗?这肯定是有原因的。
|
q*c 发帖数: 9453 | 3 ...actually I wanted to ask is
为啥不在变量退出 scope 的时候就 check 一下 reference, 没有的话就自动 destroy
...
【在 c*m 的大作中提到】![](/moin_static193/solenoid/img/up.png) : C#'s destructor: : 1. Automatic way: GC : 2. Manual way: Finalize()
|
k***r 发帖数: 4260 | 4 难道GC不是这么做的?
destroy
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : ...actually I wanted to ask is : 为啥不在变量退出 scope 的时候就 check 一下 reference, 没有的话就自动 destroy : ...
|
c*m 发帖数: 1114 | 5 1.首先那些local的数组/内嵌class/reference呀啥的在object退出时候被GC直接干掉。
2.那些reference变量new出来的玩意GC干不掉,需要用Finalize()手工干掉。
原因很简单,1那些在编译时候就定好了,.Net知道怎么干掉,2那些reference开的空间
是运行时候动态分配的,.Net还没有智能到分析你代码的程度,所以它不知道干掉多少
。或者说.Net认为编译添加对new之类的track,开销不值得。
destroy
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : ...actually I wanted to ask is : 为啥不在变量退出 scope 的时候就 check 一下 reference, 没有的话就自动 destroy : ...
|
q*c 发帖数: 9453 | 6 不是说 GC 销毁对象的时间不定? 我倒是想比如自动回收文件, 就是
不能确定什么时候 finalize 被 call...甚至会不会被 call 都不一定。
掉。
空间
【在 c*m 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 1.首先那些local的数组/内嵌class/reference呀啥的在object退出时候被GC直接干掉。 : 2.那些reference变量new出来的玩意GC干不掉,需要用Finalize()手工干掉。 : 原因很简单,1那些在编译时候就定好了,.Net知道怎么干掉,2那些reference开的空间 : 是运行时候动态分配的,.Net还没有智能到分析你代码的程度,所以它不知道干掉多少 : 。或者说.Net认为编译添加对new之类的track,开销不值得。 : : destroy
|
c*m 发帖数: 1114 | 7 GC的机制是满了才销毁。
Finalize()就是.Net提供消除那些New的玩意的工具。class退出时候会被call。 但你也
可以随时手工call Finalize(). 你把它看作一个函数就完了。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 不是说 GC 销毁对象的时间不定? 我倒是想比如自动回收文件, 就是 : 不能确定什么时候 finalize 被 call...甚至会不会被 call 都不一定。 : : 掉。 : 空间
|
h*****0 发帖数: 4889 | 8 因为java里没有对象变量,只有引用变量。退出scope里这个引用是没有了,但实际的
对象永远不会有scope。
destroy
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : ...actually I wanted to ask is : 为啥不在变量退出 scope 的时候就 check 一下 reference, 没有的话就自动 destroy : ...
|
f*****Q 发帖数: 1912 | 9 文件串口handle什么的close不行么?对象还在但是资源释放了不就行了?
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是为啥有 GC 的语言, 像 c# 和 java, 就没有destructor. 很多的时候 : desctructor 那是非常的有用, 特别是非内存的那些文件啊, 外设什么的。 : 同样的变量生命周期控制, 退栈的时候消灭。 : 如果有 destructor + GC 岂不是把两样的好处都拿到了吗?这肯定是有原因的。
|
g*****g 发帖数: 34805 | 10 非内存的资源自然是要手工回收的。比如数据库,网络连接。
在java里都是要显式关闭的。大多数API都设了timeout来
防止过长的空闲连接,那是另回事。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是为啥有 GC 的语言, 像 c# 和 java, 就没有destructor. 很多的时候 : desctructor 那是非常的有用, 特别是非内存的那些文件啊, 外设什么的。 : 同样的变量生命周期控制, 退栈的时候消灭。 : 如果有 destructor + GC 岂不是把两样的好处都拿到了吗?这肯定是有原因的。
|
|
|
g*****g 发帖数: 34805 | 11 这个说法也是错误的,GC本身就是一个并行跑的线程。
至于什么时候会触发或者说piority会提高是一个配置的问题。
并不一定要等到内存满了。
GC本身就有多种算法可以配,通常对young generation跟tenured generation
的GC算法也不一样。
你也
【在 c*m 的大作中提到】![](/moin_static193/solenoid/img/up.png) : GC的机制是满了才销毁。 : Finalize()就是.Net提供消除那些New的玩意的工具。class退出时候会被call。 但你也 : 可以随时手工call Finalize(). 你把它看作一个函数就完了。
|
g*****g 发帖数: 34805 | 12 外部资源是不能自动回收的,因为往往有一整个方法要调。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 不是说 GC 销毁对象的时间不定? 我倒是想比如自动回收文件, 就是 : 不能确定什么时候 finalize 被 call...甚至会不会被 call 都不一定。 : : 掉。 : 空间
|
q*c 发帖数: 9453 | 13 ..这个对于局部变量 compiler 还是可以check的,看看有没有额外引用就行了。
【在 h*****0 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 因为java里没有对象变量,只有引用变量。退出scope里这个引用是没有了,但实际的 : 对象永远不会有scope。 : : destroy
|
q*c 发帖数: 9453 | 14 就是想在局部变量退出 scope 的时候自动化。
但是有了 GC 就不行, 也不知道为什么不设置自动的 destructor。
【在 f*****Q 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 文件串口handle什么的close不行么?对象还在但是资源释放了不就行了?
|
q*c 发帖数: 9453 | 15 那不是, 你看很多 c++ class 就是把这些资源 wrap 起来, 把
回收放在 destructor 里面, 这样就算是 exception 也能
自动的收拾干净。 为啥一定要手动回收。
就是不知道为啥 java 就不给这么干。
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 非内存的资源自然是要手工回收的。比如数据库,网络连接。 : 在java里都是要显式关闭的。大多数API都设了timeout来 : 防止过长的空闲连接,那是另回事。
|
q*c 发帖数: 9453 | 16 so? C++ 就行。 不就是一个方法, 调就调, 有啥问题。
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 外部资源是不能自动回收的,因为往往有一整个方法要调。
|
q*c 发帖数: 9453 | 17 就是不想手动的干。
【在 f*****Q 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 文件串口handle什么的close不行么?对象还在但是资源释放了不就行了?
|
g*****g 发帖数: 34805 | 18 不是不能干,而是调用的时间是不确定的。
C++你调delete的时候destructor就调用了。
Java里不能保证什么时候GC,finalize被
调用的时候,有可能你把数据库连接,网络
连接啥的很没必要地占用了很长时间,这个
问题可大可小,但总不如显式调用合适。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 那不是, 你看很多 c++ class 就是把这些资源 wrap 起来, 把 : 回收放在 destructor 里面, 这样就算是 exception 也能 : 自动的收拾干净。 为啥一定要手动回收。 : 就是不知道为啥 java 就不给这么干。
|
q*c 发帖数: 9453 | 19 我就是奇怪的是,为啥 java 不像 c++ 一样吧某些
变量放在 stack 上, 函数推出的时候自动清理调用 destructor.
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 不是不能干,而是调用的时间是不确定的。 : C++你调delete的时候destructor就调用了。 : Java里不能保证什么时候GC,finalize被 : 调用的时候,有可能你把数据库连接,网络 : 连接啥的很没必要地占用了很长时间,这个 : 问题可大可小,但总不如显式调用合适。
|
g*****g 发帖数: 34805 | 20 因为没有destructor。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 我就是奇怪的是,为啥 java 不像 c++ 一样吧某些 : 变量放在 stack 上, 函数推出的时候自动清理调用 destructor.
|
|
|
r****t 发帖数: 10904 | 21
Yes, so python gets both. Subtlety arises when one gets both
circular reference AND customized destructors at the same
time, in that case GC is not clever enough to know where and
how (the sequence) to break the circle, and will leave the
resource around.
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是为啥有 GC 的语言, 像 c# 和 java, 就没有destructor. 很多的时候 : desctructor 那是非常的有用, 特别是非内存的那些文件啊, 外设什么的。 : 同样的变量生命周期控制, 退栈的时候消灭。 : 如果有 destructor + GC 岂不是把两样的好处都拿到了吗?这肯定是有原因的。
|
h*****0 发帖数: 4889 | 22 再说一遍,java里没有对象变量,像:
void foo() {
A a;
//...
}
里面的a不是一个对象,而是一个引用。对象是运态生成的,编译器根本无法确定a指向
的对象是否有别的引用。对象回收是Runtime GC
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : ..这个对于局部变量 compiler 还是可以check的,看看有没有额外引用就行了。
|
h*****0 发帖数: 4889 | 23 因为java没有destructor...
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 那不是, 你看很多 c++ class 就是把这些资源 wrap 起来, 把 : 回收放在 destructor 里面, 这样就算是 exception 也能 : 自动的收拾干净。 为啥一定要手动回收。 : 就是不知道为啥 java 就不给这么干。
|
h*****0 发帖数: 4889 | 24 delete a算不算手动?只有对象变量才能自动销毁。java没有对象变量,所有对象都是
new出来并返回一个引用的。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是不想手动的干。
|
h*****0 发帖数: 4889 | 25 因为这样会造成
1. 语言变得麻烦
2. 违反很多面向对象原则
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 我就是奇怪的是,为啥 java 不像 c++ 一样吧某些 : 变量放在 stack 上, 函数推出的时候自动清理调用 destructor.
|
q*c 发帖数: 9453 | 26 ..成循环逻辑了.. 算了算了, 呵呵,
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 因为没有destructor。
|
f*****Q 发帖数: 1912 | 27 这就是钻了理想的牛角尖了。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 就是不想手动的干。
|
f*****Q 发帖数: 1912 | 28 因为smalltalk->objectiveC->java->C# 这一路的语言都是有理想的语言。
【在 q*c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 我就是奇怪的是,为啥 java 不像 c++ 一样吧某些 : 变量放在 stack 上, 函数推出的时候自动清理调用 destructor.
|
q*c 发帖数: 9453 | 29 wth...haha. This ia a good reason :)
【在 f*****Q 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 因为smalltalk->objectiveC->java->C# 这一路的语言都是有理想的语言。
|
c*****t 发帖数: 1879 | 30 finalize () can serve as the destructor in some sense.
With incremental gc, it is possible to track and delete the object
when the scope / function exited when the reference count is 0, but
the execution of finalize () might not be at a place where one might
know beforehand.
So, it is also different from destructor in C++ which you expect it
to be executed in certain places.
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 因为没有destructor。
|
|
|
g*****g 发帖数: 34805 | 31 You don't know when an object is going to be reclaimed.
For cirtical resource, this can be a big issue.
【在 c*****t 的大作中提到】![](/moin_static193/solenoid/img/up.png) : finalize () can serve as the destructor in some sense. : With incremental gc, it is possible to track and delete the object : when the scope / function exited when the reference count is 0, but : the execution of finalize () might not be at a place where one might : know beforehand. : So, it is also different from destructor in C++ which you expect it : to be executed in certain places.
|
c*****t 发帖数: 1879 | 32 Right. For critical resources, one has to do it manually. It can
be somewhat a pain, but not necessarily a bad thing.
【在 g*****g 的大作中提到】![](/moin_static193/solenoid/img/up.png) : You don't know when an object is going to be reclaimed. : For cirtical resource, this can be a big issue.
|
q*********u 发帖数: 280 | 33 这个说对的好阿, 没有对象变量,
c++里面A a(xx, xx, ...)这样, 直接一个A的实体就出来了,
java不可以,这样就出现goodbug所说的, java的A的reference a所指的entity不
知道什么时候还会被别的reference比如b来指.
其实一般情况下没有太多必要要马上gc, 和c++一样实时, 如果真的有需要,就要参
考soft, weak, phantom reference了
再说一遍,java里没有对象变量,像:
void foo() {
A a;
//...
}
里面的a不是一个对象,而是一个引用。对象是运态生成的,编译器根本无法确定a指向
的对象是否有别的引用。对象回收是Runtime GC
【在 h*****0 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 再说一遍,java里没有对象变量,像: : void foo() { : A a; : //... : } : 里面的a不是一个对象,而是一个引用。对象是运态生成的,编译器根本无法确定a指向 : 的对象是否有别的引用。对象回收是Runtime GC
|