建站资讯

Java中为何不设置一个函数,让程序猿来标记可以

作者:admin 发布时间:2020-07-27

 

题主你的问题里不是已经包含了答案了吗。“这些变量其实还有引用的,GC也释放不误”。

那释放之后,那些“指向着一个已经释放了的对象的引用”被使用时会发生什么情况?

如果不做任何额外处理,那便是“未定义行为”,如果该段内存还没被覆盖,那就看起来对象还可用,如果被覆盖成其他数据了,会发生什么那就谁都不清楚了。

如果做点特殊处理,那你就得引入“已经失效的引用”这个概念,那这个“失效”的标记长在哪儿?如果在本来放对象的内存中,那这段内存根本就释放不了(释放了你也得在那里保持个失效标记)。如果在标记在引用本身上,那么谁去设置这些标记,这个“释放函数”还不是得查找“所有指向这段内存的引用”,如果在查找过程当中又产生了新的引用呢,还不是得stop the world。而且即使你解决了失效的问题,你的程序执行时好好的拿着个引用,唱着小歌吃着火锅,跑着跑着就引用失效了。究竟是你应该随时考虑它失效的情况,还是它本来不应该失效但是实际上它却失效了?如果是后者,究竟是谁让它失效的,即使我找到谁让它失效,究竟是释放这它的程序执行得太早,是你这段程序执行得太迟?


C#可以通过调用Dispose函数来做这个事情。那时候空间都(不是立刻)释放了,然后所有指向它的变量都只留下了一个记号,用来在你访问他的时候触发ObjectDisposedException。放弃Java,改用C#吧

我认为如果只是觉得存储空间没有释放的话其实并非什么问题,既然选择用java就只能相信他,何况jvm在这些方面花了大功夫是能可以信赖的。实际上大部分情况你要标记释放的对象jvm都能一下子就找到,比如没有逃逸的局部变量什么的。

问题在于内存之外的一些资源该怎么办。这其实确实是个问题,所以微软的c#发明了using和IDisposable来允许程序猿指定一个时间去释放一些非托管的资源(大概就是除了内存之外的资源了吧)。多数时候这个机制是很好用的。归功于此c#程序猿写io相关的代码可以省事好多——不用自己去close了。然而java里貌似并没有这种机制,如果有需要只能自己写个方法去finally……

java关于内存的另一个问题是,c#有struct而java没有哈哈哈

不过c#遇到COM对象需要立即释放的情况下也是会出问题的。如果c#能允许程序创建具有独立电子计数器的能独立与COM对象分离的RCW该多好。并不懂为何不这么做,有大神知道的话务必跟我说……

吃惊,using的类似物java已经有了。不过struct这么底层的东(hei)西(dian)大概不会改。java程序猿们还是要整天面对int和Integer和各种虽然不想但是又迫不得已new个class出来的情况哈哈哈

收缩