美文网首页
C++和Java解决智能指针或对象循环引用的策略

C++和Java解决智能指针或对象循环引用的策略

作者: ck123pm | 来源:发表于2019-06-30 16:20 被阅读0次

https://zwmf.iteye.com/blog/1738574

C++

class CDog;
class CTail
{
public:
    void RegisterDog(const std::shared_ptr<CDog>& ptr_dog)
    {
        m_dog_ = ptr_dog;
    }
private:
    std::weak_ptr<CDog> m_dog_ ;
};

class CDog
{
public:
    void RegisterTail(const std::shared_ptr<CTail>& ptr_tail)
    {
        m_tail_ = ptr_tail;
    }
private:
    std::shared_ptr<CTail> m_tail_ = nullptr;
};


// 测试智能指针
void TestRefPtr()
{
    std::shared_ptr<CDog> ptr_dog = make_shared<CDog>();
    std::shared_ptr<CTail> ptr_tail = make_shared<CTail>();
    ptr_dog->RegisterTail(ptr_tail);
    ptr_tail->RegisterDog(ptr_dog);
    cout << "ptr_dog count:" << ptr_dog.use_count()<<endl;
    cout << "ptr_tail count:" << ptr_tail.use_count() << endl;
}

int main()
{
    
    TestRefPtr();
    return 0;
}

Java

在C++中使用过智能指针的同学们应该都清楚智能指针对C++中内存管理带来的极大便利,但是也会引入一些头疼的问题,比如智能指针带来的循环引用的问题,这个问题在之前的项目中一直没有很好的解决。

    最近参与到android的项目开发,对java的内存的管理有了一个初步的了解,很容易想到了循环引用的问题。比如下面这个例子:

    public void buidDog()

    {

       Dog newDog = new Dog();

      Tail newTail = new Tail();

      newDog.tail = newTail;

      newTail.dog = newDog;

    }

    在这里,newTail中拿着对newDog的引用,newDog中拿着对newTail的引用。如果newDog要被回收,前提是newTail被先回收,这样才能释放对newDog的引用。但是反回过来,newTail要被回收的前提是newDog要被先回收。当buildDog函数退出后,看起来垃圾回收管理似乎就始终无法回收这两个实际已经不再需要的对象。

     垃圾回收机制究竟能否解决循环引用这一困境,带着这个疑问找了一些资料,找到了一个比较满意的解释。在《Java Platform Performance: Strategies and Tactics》这本书的附录A中有一处说明,这本书出自sun公司java团队员工,应该算比较权威的。其中有这样一段([http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997428](http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997428)):

“It's important to note that not just any strong reference will hold an object in memory.

These must be references that chain from a garbage collection root. 

GC roots are a special class of variable that includes 

Temporary variables on the stack (of any thread)

    Static variables (from any class)

    Special references from JNI native code”。

这段话可以简单的理解就是强引用并不能保证对象不被回收。垃圾回收机制除了检查对象是否被引用外,还要看对象是否被至少一个GC roots对象直接或者间接引用。GC roots对象包括以下一些类容:

1 每个线程当前的函数调用栈,从栈顶到栈底的每个函数里的局部变量。

2 静态的变量

3 被jni中引用到的变量。

    所以,上面例子中两个循环引用的对象,虽然都存在一个强引用,但是不被任何GC root对象直接或者间接引用到,垃圾回收机制能够发现这个问题。

    另外,为了验证这一点,特意翻看了一下android源码中GC管理这一块的代码。在MarkSweep.c这文件中,有一个void dvmHeapMarkRootSet()函数,这个函数对于GC root对象,有一些详细的说明,有兴趣的可以细看一下。

    所以,java对于循环引用有一套自己的解决方案。但是话又说回来,一般实际编码中出现的循环引用不会是上面那个例子那样明显,一般都是多个对象复杂的引用导致的循环,这个时候,如果一个对象的生命周期很长,就会导致多个对象都释放不了,所以还是要特别留意对象之间的引用关系。

转载于:http://blog.sina.com.cn/s/blog_6a0eedb60100y76b.html

相关文章

  • C++和Java解决智能指针或对象循环引用的策略

    https://zwmf.iteye.com/blog/1738574 C++ Java 在C++中使用过智能指针...

  • java中的引用与c++中的指针的区别

    java中的引用与c++中的指针的区别 Java的引用和C++的指针都是指向一块内存地址的,通过引用或指针来完成对...

  • C++智能指针学习

    C++智能指针学习 [toc] 智能指针内存管理要解决的根本问题是:一个堆对象,在被多个对象引用时,如何释放资源的...

  • C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 辅助类 智能指针类 使用测试 参考: C++ 引用计数技术及智能指针...

  • Android之智能指针

    什么是智能指针 智能指针是C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。 在Android...

  • Java四种引用简介

    引语: 我们知道java相比C,C++中没有令人头痛的指针,但是却有和指针作用相似的引用对象(Reference)...

  • java的四种引用

    引语: 我们知道java相比C,C++中没有令人头痛的指针,但是却有和指针作用相似的引用对象(Reference)...

  • 基于堆栈内存详析 Java函数形参是传值还是引用? | C++指

    Java的引用 及 Java函数形参是传值还是引用 Java中没有指针的说法,Java中的引用就类似于C++的指针...

  • JVM&GC(一)java引用

    前言 Java中的引用有点像C++中的指针,通过引用可以对堆中的对象进行操作。在Java程序中最常见的引用类型是强...

  • 面试总结(2017.7.27)

    Android 的四大引用 1.强引用 Java中的强引用,类似于C++的指针。通过引用,可以对堆中的对象进行...

网友评论

      本文标题:C++和Java解决智能指针或对象循环引用的策略

      本文链接:https://www.haomeiwen.com/subject/rzzfrqtx.html