none
在一个方法(假如叫 mA)里,对另一个对象实例(假如叫 o),的实例方法 (假如叫 oA)进行调用,在 mA 完成前,对 o 的引用是否会被保留,保留在 mA 所属线程的栈里面吗? RRS feed

  • 常规讨论

  • 在一个方法(假如叫 mA)里,对另一个对象实例(假如叫 o),的实例方法 (假如叫 oA)进行调用,在 mA 完成前,对 o 的引用是否会被保留,保留在 mA 所属线程的栈里面吗?

    mA 是通过一个共有属性 (假如叫 O) 获得 o 的,在获得后不久,也就是 oA 还没有完成前, 共有属性 O 对应的 私有属性_O 就被刷新, 也就是说, 下次访问 O 返回的值 就是 o’ 了。

    我想确认的是, mA 完成前, o 的引用是不是还被保留这,否则 _O 已经不指向 o 了, o 会不会就被垃圾回收了?也就是说 oA 方法调用没完成, o 对象就被回收了,岂不是很奇怪?


    • 已编辑 GuYuming 2017年12月1日 10:48
    • 已更改类型 GuYuming 2017年12月6日 1:22
    2017年12月1日 10:35

全部回复

  • (1) 假設 o 變量所引用的對象稱為 Pobject(引用類型的對象實例), 當有任何一個變量引用此 Pobject時,這個 Pobject 就不會被回收。

    (2) 假設 o 是 mA method 的區域變量, 那麼 o 的生命週期就是跟著 mA method 的。

    (3) 若在 mA 方法內 o(區域變量) 和 O (property) 的關係是 o=O , 此時只是代表 o 和 O 指向同一個 Pobject,所以就要看 O 的改變究竟是重新指向另一個 P'object 還是只是改變 Pobject 的屬性或欄位而已。 若 O 指向新的 P'object , 那對o 沒有影響 , 因為此時 o 依舊是指向 Pobject; 比方 Pobject 有個屬性 X , 若使用的是 O.X = ... ; 那 o.X 就會跟著改變, 因為 o 和 O 取的都是 Pobject.X

     

     


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2017年12月1日 12:00
  • 不好意思,我没讲清楚,这个问题的关键是,在 mA 里,我并没有显式的声明一个变量来存储o,直接调用的oA 方法,如下

    public void mA()

    {

    blablabla.O.oA();

    }

    这和下面的写法有区别吗?.net 会不会因为我没声明o变量就不保存这个值,进入oA后 o对象就被回收了?

    public void mA()

    {

     var o=blablabla.O;

    o.oA();

    }


    • 已编辑 GuYuming 2017年12月4日 1:47
    2017年12月4日 1:45
  • Hi,

    欢迎在MSDN论坛发帖。

    分析你提供的伪代码,并且想用C#代码实现它,发现有几处自相矛盾的地方。

    1. 这个blablabla 是namespace 的命名空间吗? O是里面的静态方法吗?  那oA这个方法如何得到?

    2. 如果0是静态类,那么oA肯定是静态方法。不然肯定会失败。

    按照上面的分析,再分析你下面的代码,就会矛盾。

    var o=blablabla.O;

    静态的类,不可能这么直接复制给o变量的,由此反推上面的猜测是错误的。

    如果blablabla 是通过new出来的对象,那么你下面的代码,这样写发也是不对的。

    我觉得你还是从生命周期的角度来考虑问题,new 出来的对象是在堆上面,需要GC释放,static 的对象是在静态存储区,随程序生命周期。

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2017年12月4日 7:05
    版主
  • blablabla 可能是一连串的对象属性引用,不是静态的,是通过new 出来的。 大写的 O 可以对应我下面帖子里面声明的 Public property Cache (类型是 CacheType), 

    https://social.msdn.microsoft.com/Forums/office/en-US/46395303-9bf9-4a15-85b5-16e193abdfe2/large-object-memory-cache-refreshing?forum=sharepointdevelopment 

    我刚读到了一些 IL Call 和 CallVirt 的区别,我读的内容好像说的是 o.oA() 这样的调用如果用CallVirt 实现,如果 o 一开始就是null, CallVirt就报错了。但没有讨论 o 这样的 Object Reference(或者叫Managed Pointer)在栈上的产生机制。我的意思是,显式地声明以 CacheType 类型变量 o (如上面伪代码2), 和不显式声明(上面伪代码1),对Object Reference 有影响吗?


    • 已编辑 GuYuming 2017年12月4日 8:55
    2017年12月4日 8:54
  • Hi,

    我建议你把帖子的类型修改成讨论贴,这样方便更多的人看到,进来参与讨论。

    我个人认为,只有定义的变量,才会有reference 的问题。

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月5日 7:41
    版主
  • blablabla 可能是一连串的对象属性引用,不是静态的,是通过new 出来的。 大写的 O 可以对应我下面帖子里面声明的 Public property Cache (类型是 CacheType), 

    https://social.msdn.microsoft.com/Forums/office/en-US/46395303-9bf9-4a15-85b5-16e193abdfe2/large-object-memory-cache-refreshing?forum=sharepointdevelopment 


    你的代码写法有问题。

    对于对象的访问,不包含NameSpace,在对象(ObjA)内部,访问其它对象(ObjB)的方法/属性,那么你需要知道有ObjB存在。

    而ObjB的存在可以通过 ObjA的属性,或构造函数等办法得到一个引用。

    楼主,你现在其实是不知道ObjB是否存在的情况下调用了它的方法 .oA();  此问题一。

    问题二,.oA()方法属于ObjB,而ObjB是属于其它对象(设:ObjC),那么,要调用ObjB.oA()方法,你需要做的不是

    ObjC.ObjB.oA();  而是 ObjC.ExecA();  在ExecA()里调用ObjB.oA()方法。因为ObjB不属于ObjA,它属于ObjC。

    这个可以避免跨对象调用时,中间对象为null情况的出现。

    再者,出现这种跨对象调用时,你要么添加私有对象引用 ,要么修改代码框架

    2017年12月13日 2:35
  • Hi,

    根据你的描述。

    blablabla.O.oA(); 这行代码中blablabla.O本身不就是一个引用么。该引用存在于堆内存  

    var o=blablabla.O;这行代码只是将blablabla.O这个引用的值赋值给o这个引用变量。o这个引用存在于栈内存。

    上面两种写法都是有一个引用指向那个实例对象的,所以.Net应该不会回收该对象的实例。

    以上纯个人看法,如有不正还望指正


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    2018年1月5日 6:34