精华内容
下载资源
问答
  • 主要介绍了C语言中的符号、弱符号、强引用和弱引用的定义及相关内容,非常的简单易懂,有需要的朋友可以参考下
  • 【C++】强引用和弱引用

    千次阅读 2018-10-10 12:10:56
    链接器处理强引用和弱引用的过程几乎是一样的,只是对于未定义的弱引用,链接器不认为它是一个错误,一般默认其为 0(地址为 0),或者是一个特殊的值,以便程序代码能够识别。 __attribute__((weak)) extern int ...

    链接器处理强引用和弱引用的过程几乎是一样的,只是对于未定义的弱引用,链接器不认为它是一个错误,一般默认其为 0(地址为 0),或者是一个特殊的值,以便程序代码能够识别。

    __attribute__((weak)) extern int a;
    
    printf("a = %d\n", a);

    我们可以将它编译成一个可执行文件,GCC 并不会报链接错误。但是当程序运行时,输出&a: 0, func: 0后就会发生段错误(Segment Fault),这是因为符号 a 和 func 的地址都为 0,这个地址是禁止访问的。
     

     

    代码中需要判断的是地址,不是值,所以变量 a 前面需要加&;而函数名本身就表示地址,所以 func 前边不需要&

     

     

    弱引用和强引用非常利于程序的模块化开发,我们可以将程序的扩展模块定义为弱引用,当我们将扩展模块和程序链接在一起时,程序就可以正常使用;如果我们去掉了某些模块,那么程序也可以正常链接,只是缺少了某些功能,这使得程序的功能更加容易裁剪和组合。

    展开全文
  • 一、强引用 如下是强引用的经典形式: object o = new object(); 特点: (1)创建一个对象,并将对这个对象的引用赋值给o,这样就是强引用了 (2)当内存空间不足的时候,虚拟机宁愿抛出错误,也不愿意回收...

    一、强引用

    如下是强引用的经典形式:

    object o = new object();

    特点:

    (1)创建一个对象,并将对这个对象的引用赋值给o,这样就是强引用了

    (2)当内存空间不足的时候,虚拟机宁愿抛出错误,也不愿意回收内存

    (3)可以使用 o = null;的方式来弱化引用

    (4)如果一个对象,没有一个引用来指向他,那么这个引用可以被垃圾回收

    二、软引用

    softReference<String> softRef = new softReference<String>(str);

    特点:

    (1)软引用可以实现内存敏感的高速缓存

    (2)当内存空间不足的时候,就回收这些对象

    (3)hold on until you can't

    三、弱引用

    WeakReference<String> weakRef = new WeakReference<String>(str);

    (1)弱引用和软引用的区别在于其拥有更短的生命周期

    (2)不管当前的内存空间是否足够,都会回收他的内存

    (3)偶尔才使用到的对象,我们使用弱引用的机制

    四、总结

    他们之间的关系:SoftReference > WeakReference > PhantomReference

    如下是几种引用的回收和生命周期图

     

    同名原创公众号: 程序大视界

     

    展开全文
  • C++ - 强引用和弱引用

    2018-01-18 18:38:28
    强引用当对象被创建时,计数为1;每创建一个变量引用该对象时,该对象的计数就增加1;当上述变量销毁时,对象的计数减1,当计数为0时,这个对象也就被析构了。强引用计数在很多种情况下都是可以正常工作的,但是也有...

    强引用

    当对象被创建时,计数为1;每创建一个变量引用该对象时,该对象的计数就增加1;当上述变量销毁时,对象的计数减1,当计数为0时,这个对象也就被析构了。
    强引用计数在很多种情况下都是可以正常工作的,但是也有不凑效的时候,当出现循环引用时,就会出现严重的问题,以至于出现内存泄露,如下代码:
    #include   
    #include   
    #include   
    #include   
      
    class parent;  
    class children;  
      
    typedef boost::shared_ptr parent_ptr;  
    typedef boost::shared_ptr children_ptr;  
      
    class parent  
    {  
    public:  
        ~parent() { std::cout <<"destroying parent\n"; }  
      
    public:  
        children_ptr children;  
    };  
      
    class children  
    {  
    public:  
        ~children() { std::cout <<"destroying children\n"; }  
      
    public:  
        parent_ptr parent;  
    };  
      
    void test()  
    {  
        parent_ptr father(new parent());  
        children_ptr son(new children);  
      
        father->children = son;  
        son->parent = father;  
    }  
      
    void main()  
    {  
        std::cout<<"begin test...\n";  
        test();  
        std::cout<<"end test.\n";  
    }  
    

    运行该程序可以看到,即使退出了test函数后,由于parent和children对象互相引用,它们的引用计数都是1,不能自动释放,并且此时这两个对象再无法访问到。这就引起了c++中那臭名昭著的内存泄漏。
    一般来讲,解除这种循环引用有下面有三种可行的方法:
    1. 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
    2. 当parent的生存期超过children的生存期的时候,children改为使用一个普通指针指向parent。
    3. 使用弱引用的智能指针打破这种循环引用。
    虽然这三种方法都可行,但方法1和方法2都需要程序员手动控制,麻烦且容易出错。下面就介绍弱引用
     
    在多线程程序中,一个对象如果被多个线程访问,一般使用shared_ptr,通过引用计数来保证对象不被错误的释放导致其他线程访问出现问题。
    但这种引用计数解决不了循环引用的问题
     

    弱引用

    boost::weak_ptr是boost提供的一个弱引用的智能指针,它的声明可以简化如下:
    namespace boost {  
      
        template<</span>typename T> class weak_ptr {  
        public:  
            template <</span>typename Y>  
            weak_ptr(const shared_ptr& r);  
      
            weak_ptr(const weak_ptr& r);  
      
            ~weak_ptr();  
      
            T* get() const;   
            bool expired() const;   
            shared_ptr lock() const;  
        };   
    }  

    定义变量:
    shared_ptr<T>  t(new T);
    weak_ptr<T> ptr(t); // t为一个T对象 
    则当t被销毁时,ptr 被自动置为无效。使用方法如下:
    if ( shard_ptr<T>  safePtr  = ptr.lock() )  safePtr->Fun();
     
    可以看到,boost::weak_ptr必须从一个boost::share_ptr或另一个boost::weak_ptr转换而来,这也说明,进行该对象的内存管理的是那个强引用的boost::share_ptr。boost::weak_ptr只是提供了对管理对象的一个访问手段。boost::weak_ptr除了对所管理对象的基本访问功能(通过get()函数)外,还有两个常用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针。
    由于弱引用不更改引用计数,类似普通指针,只要把循环引用的一方使用弱引用,即可解除循环引用。对于上面的那个例子来说,只要把children的定义改为如下方式,即可解除循环引用:
    class children  
    {  
    public:  
        ~children() { std::cout <<"destroying children\n"; }  
      
    public:  
        boost::weak_ptr parent;  
    };  

    最后值得一提的是,虽然通过弱引用指针可以有效的解除循环引用,但这种方式必须在程序员能预见会出现循环引用的情况下才能使用,也可以是说 弱引用仅仅是一种编译期的解决方案,如果程序在运行过程中出现了循环引用,还是会造成内存泄漏的。因此,不要认为只要使用了智能指针便能杜绝内存泄漏。毕竟,对于C++来说,由于没有垃圾回收机制,内存泄漏对每一个程序员来说都是一个非常头痛的问题。
     
    弱引用:它仅仅是对象 存在时候的引用,当对象不存在时弱引用能够检测到,从而避免非法访问,弱引用也不会修改对象的引用计数。这意味这弱引用它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱引用能检测到所管理的对象是否已经被释放,从而避免访问非法内存。
    展开全文
  • 其实这个问题是Java面试中比较常见的问题,按难度来划分的话应该只是中等难度,之前也了解过它们的区别,但是实际开发过程几乎很少使用导致只是纯粹记忆,本文将系统的整理强引用,软引用,弱引用和虚引用的区别,并...

    目录

    一、什么是强引用,软引用,弱引用,虚引用?

    1.强引用(StrongReference)

    2.软引用(SoftReference)

    3.弱引用(WeakReference)

    4.虚引用(PhantomReference)

    5.四种引用的区别

    二、引用的使用场景

    1.强引用(StrongReference)

    2.软引用(SoftReference)

    3.弱引用(WeakReference)

    4.虚引用(PhantomReference)


    这个问题是阿里菜鸟网络一面面试官的提问,由于个人准备不够充分以及知识储备不足没有答出问题根本。其实这个问题是Java面试中比较常见的问题,按难度来划分的话应该只是中等难度,之前也了解过它们的区别,但是实际开发过程几乎很少使用导致只是纯粹记忆,本文将系统的整理强引用,软引用,弱引用和虚引用的区别,并结合具体场景探究一下它们的用法。

    一、什么是强引用,软引用,弱引用,虚引用?

    JDK1.2 以前,如果一个对象不被任何变量引用,则程序无法再次使用这个对象,这个对象最终会被 GC(GabageCollection:垃圾回收)。但是如果之后可能还会用到这个对象,就只能去新建一个了,这其实就降低了 JVM 性能,没有达到最大的优化策略。

    JDK1.2 开始,提供了四种类型的引用:强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。主要有两个目的:1.可以在代码中决定某些对象的生命周期;2.优化JVM的垃圾回收机制。

    1.强引用(StrongReference)

    强引用是程序代码之中普遍存在的,我们一般创建对象的过程都是强引用,如下面代码。

        Object object = new Object();
        String str = "123";  

    如果某个对象有强引用与之关联,Java虚拟机(JVM)必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory 错误也不会回收这种对象。基于上述情况,我们在使用完对象后如果想让 JVM 回收对象需要将对象弱化,具体操作是将其引用置为null。(补充说明:局部方法内的强引用会随着方法的结束退栈而自动清除引用,全局变量需要在不使用时置null

        Object strongReference = new Object();
        strongReference = null;

    Java集合类的强引用弱化方式不能采取置 null 方式,因为这种方式强引用依然存在,只有采用 clear()方法内存数组中存放的引用类型进行内存释放,这样才可以及时释放内存。

            ArrayList<Integer> arrays = new ArrayList<>(10);
            arrays.add(1);
            arrays.add(2);
            arrays.add(3);
            arrays.clear();//不使用时 clear 清除数组

    查看 ArrayList clear 方法的源码发现是遍历元素数组将每个元素置为 null ,即 elementData[i] = null

    2.软引用(SoftReference

    软引用是用来描述一些有用但并不是必需的对象,适合用来实现缓存(比如浏览器的‘后退’按钮使用的缓存),JVM内存空间充足的时候将数据缓存在内存中,如果空间不足了就将其回收掉。

        // 强引用
        String strongReference = new String("123");
        // 软引用,"456"这个String对象包含一个强引用 str 和弱引用 softReference 
        String str = new String("456");
        SoftReference<String> softReference = new SoftReference<String>(str);

    软引用可以和一个引用队列(ReferenceQueue)联合使用。如果软引用所引用对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。

        ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
        String str = new String("abc");
        SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);
    
        str = null;//去掉 str 的强引用
        System.gc();// Notify GC
    
        System.out.println(softReference.get()); // abc
    
        Reference<? extends String> reference = referenceQueue.poll();
        System.out.println(reference); //null

    软引用对象是在jvm内存不够的时候才会被回收,我们调用System.gc()方法只是起通知作用,JVM什么时候扫描回收对象是JVM自己的状态决定的。即使扫描到软引用对象也不一定会回收它,只有内存不够的时候JVM才会回收。

    3.弱引用(WeakReference)

    弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象,在java中用java.lang.ref.WeakReference 类来表示。

    弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期,它只能生存到下一次垃圾收集发生之前。当垃圾回收器扫描到只具有弱引用的对象时,无论当前内存空间是否足够,都会回收它。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

        String str = new String("abc");
        WeakReference<String> weakReference = new WeakReference<>(str);
        str = null;//去掉强引用

    如果一个对象是偶尔(很少)的使用,并且希望在使用时随时就能获取到,但又不想影响此对象的垃圾收集,那么我们应该用WeakReference 来标记此对象。

    弱引用也可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

        String person = new String ("123");
        ReferenceQueue<Person> queue = new ReferenceQueue<>();
        WeakReference<Person> weakReference = new WeakReference<Person>(person, queue);
    
        person = null;//去掉强引用

    4.虚引用(PhantomReference)

    与其他三种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

    虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃 圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

        String str= new String();
        ReferenceQueue queue = new ReferenceQueue ();
        // 创建虚引用,要求必须与一个引用队列关联
        PhantomReference pr = new PhantomReference (str, queue); 

    虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

    程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要进行垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

    5.四种引用的区别

    根据上面对四种引用的介绍,按照引用被回收的机制特点总结了它们的区别如下。

    级别何时被GC回收生成时间
    强引用从来不会JVM停止时
    软引用内存空间不足时内存不足时终止
    弱引用对象未被引用时GC后终止
    虚引用对象被回收时内存使用控制引用队列对象被回收

    二、引用的使用场景

    1.强引用(StrongReference)

    强引用是我们日常代码中最常见的,这里不再赘述,只需要注意当强引用对象不再使用需要回收时要将引用变量置为 null,另外集合对象的置空需要使用 clear 方法。

    2.软引用(SoftReference

    软引用的回收机制使得它非常适合用于创建缓存,当系统内存不足的时候,缓存中的内容是可以被释放的。

    • 图片缓存。图片缓存框架中,“内存缓存”中的图片是以这种引用保存,使得 JVM 在发生 OOM 之前,可以回收这部分缓存。
    • 网页缓存。
    Browser prev = new Browser();               // 获取页面进行浏览
    SoftReference sr = new SoftReference(prev); // 浏览完毕后置为软引用		
    if(sr.get()!=null) { 
    	rev = (Browser) sr.get();           // 还没有被回收器回收,直接获取
    } else {
    	prev = new Browser();               // 由于内存吃紧,所以对软引用的对象回收了
    	sr = new SoftReference(prev);       // 重新构建
    }

    3.弱引用(WeakReference)

    当发生GC时,弱引用对象总会被回收,因此弱引用也可以用于缓存。

    •  ThreadLocalMap防止内存泄漏
    • 监控对象是否将要被回收
    Object obj = new Object();
    WeakReference<Object> wf = new WeakReference<Object>(obj);//创建弱引用
    wf.get();//有时候会返回null
    wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾
    System.gc();  //通知JVM的gc进行垃圾回收,但JVM不一定会立刻执行
    wf.get();//此时会返回null

    4.虚引用(PhantomReference)

    虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

    • 它允许你知道具体何时其引用的对象从内存中移除。这一点尤其表现在处理类似图片的大文件的情况。当你确定一个图片数据对象应该被回收,你可以利用虚引用来判断这个对象回收之后在继续加载下一张图片。这样可以尽可能地避免可怕的内存溢出错误。

    • 虚引用可以避免很多析构时的问题。finalize 方法可以通过创建强引用指向快被销毁的对象来让这些对象重新复活。然而,一个重写了 finalize 方法的对象如果想要被回收掉,需要经历两个单独的垃圾收集周期。在第一个周期中,某个对象被标记为可回收,进而才能进行析构。

    展开全文
  • python3学习笔记之 强引用和弱引用

    千次阅读 2018-04-12 22:57:24
    python中,名字对象的关联是强引用的关系,会增加引用计数,进而影响目标对象的生命周期。所以 弱引用就是在保留引用的前提下,不增加计数,不阻止目标被回收。但不是所有的类型都支持弱引用(如 int、str、list、...
  • 首先我表示很悲剧,在看《程序员的自我修养--链接、装载与库》之前我竟不知道C有符号、弱符号、强引用和弱引用。在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样感觉的朋友交流也希望...
  • Java基础篇 - 强引用弱引用、软引用和虚引用

    万次阅读 多人点赞 2018-09-09 08:58:21
    引用计数:Java堆中每一个对象都有一个引用计数属性,引用每新增1次计数加1,引用每释放1次计数减1。 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象...
  • Java:强引用,软引用,弱引用和虚引用

    万次阅读 多人点赞 2019-01-02 16:56:19
    一、强引用 二、软引用 三、弱引用 四、虚引用 五、总结 在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及状态,程序才能使用它。这就像在商店...
  • 很早Java API就添加了弱引用(WeakReference)软引用(SoftReference),但并不是所有的程序员都熟悉这两个概念
  • 1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为: 强引用 >... 弱引用 > 虚引用 ⑴强引用(StrongReference) 强引用是使用最普遍的引用。如果一个对象具...
  • 结合`u-boot`和`kernel`来说明GCC中的符号和弱符号以及强引用和弱引用
  • C#中的强引用和弱引用

    千次阅读 2018-07-17 21:55:40
    我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用可以让您保持对对象的...
  • C# 强引用和弱引用

    千次阅读 2013-04-01 17:08:49
    在.NET中弱引用通过System.WeakReference类实现。弱引用为引用的对象提供一项机制,使被引用的对象能够被垃 圾收集器作用。ASP.NET高速缓存就使用了弱引用。如果内存使用率太高,高速缓存将被清除。 强制垃圾收集 ...
  • Java中JVM负责内存的分配回收,这个是它的优点,同时也是它的缺点。为了解决它的缺点,可以使用软引用等方法来解决。
  • 1、强引用(StrongReference) 最普遍的一种引用方式,如String s = “abc”,变量s就是字符串“abc”的强引用,只要强引用存在,则垃圾回收器就不会回收这个对象。 2、软引用(SoftReference) 用于描述还有用但非...
  • 众所周知,Java中是JVM负责内存的分配回收,这是它的优点(使用方便,程序不用再像使用c那样操心内存),但同时也是它的缺点(不够灵活)。为了解决内存操作不灵活这个问题,可以采用软引用等方法。 在JDK1.2以前...
  • Objective-C 强引用和弱引用

    千次阅读 2017-03-02 20:23:21
    Objective-C默认声明的一个对象就为__strongid obj1 = [[NSObject alloc] init];id __strong obj1 = [[NSObject alloc] init];等价的 ...强引用可以释放对象,但弱引用不可以,因为弱引用不持有对象
  • 强引用,软引用,弱引用

    千次阅读 2018-05-25 14:10:39
    一、软引用和弱引用的用法软引用(SoftReference)的含义是,如果一个对象只具有软引用,而当前虚拟机堆内存空间足够,那么垃圾回收器就不会回收它,反之就会回收这些软引用指向的对象。弱引用(WeakReference)与软...
  • 一、强引用 Java中的引用,类似于C++的指针。通过引用,可以对堆中的对象进行操作。在某个函数中,当创建了一个对象,该对象被分配在堆中,通过这个对象的引用才能对这个对象进行操作。 假设以上代码是在方法内...
  • 架构 强引用:当内存不足,JVM开始垃圾回收,对于强引用的对象,就算出现了OOM也不会对该对象进行回收。 通常我们所使用的百分之95都是强引用。例如Object object=new Object...弱引用:WeakReference对于弱引用的...
  • 强引用和弱引用(__strong和__weak)

    千次阅读 2015-11-29 11:58:43
    初学者干货   在OC ARC模式下开发: id objcA =[ [NSObject alloc] init];...注:在强引用中,有时会出现循环引用的情况,这时就需要弱引用(__weak)来帮忙 ,如本博客里面提到的block的循环引
  • 符号和弱符号  在编程中碰到一种情况叫符号重复定义。多个目标文件中含有相同名字的全局变量的定义,那么这些目标文件链接的时候就会出现符号重复定义的错误。比如在目标文件 A 目标文件 B 都定义了一个...
  • 弱引用强引用

    千次阅读 2017-12-27 21:16:50
     C++中存在两种语义:值语义(value sematics)对象语义(object sematic),对象语义也可以叫做引用语义(reference sematics)。 值语义,指的是对象的拷贝与原对象无关,就像拷贝int一样,C++的常用类型数据...
  • 1.强引用(StrongReference) 我们常见的普通对象的引用 例如Object object = new Object(); 特点:只要强引用指向一个对象,就表明这个对象是”活的”,jvm宁可抛出OutOfMemoryError,也不会去回收这个对象。对于...
  • 强引用,软引用,弱引用,虚引用 强引用指的是代码中普遍存在的Object obj=new Object()这类的引用,只要强引用存在,垃圾收集器就不会回收被引用的对象, 软引用,有些有用但是并非必须的对象,在系统将要发生内存...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,696
精华内容 41,478
关键字:

强引用和弱引用

友情链接: markerclusterer.zip