zoukankan      html  css  js  c++  java
  • 内存问题

    1.

    什么情况下会发生内存泄漏和内存溢出?

    答:当程序在申请内存后,无法释放已申请的内存空间(例如一个对象或者变量使用完成后没有释放,这个对象一直占用着内存),一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。内存泄露会最终会导致内存溢出!

    当程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢出。

    2.

    自动释放池底层怎么实现

    答:自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。当一个对象收到发送autorelease消息时,它被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除, 并且会给池子里面所有的对象都会做一次release操作.

    3

    简述OC中 内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是 release,为什 么?readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak属性的作 用?

     

    答:OC中内存管理机制应该就是引用计数的增减吧,retainCount为0时释放该内存。

          retain对应的是release,内存的释放用release。

          alloc对应的是dealloc,内存的销毁用dealloc。

          readwrite此标记说明属性会被当成读写的,这也是默认属性。

          readonly此标记说明属性只可以读,也就是不能设置,可以获取。

          assign不会使引用计数加1,也就是直接赋值。

          retain会使引用计数加1。

          copy建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。

          nonatomic:非原子性访问,多线程并发访问会提高性能。

          atomic:原子性访问。

          strong:打开ARC时才会使用,相当于retain。

          weak:打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。

     

     

    4.

    堆栈的区别:

    答:(1)管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生 memory leak。

    (2)申请大小:能从栈获得的空间较小,堆是向高地址扩展的数据结构,是不连续的内存区域。堆的大小受限于计算机系统中 有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    (3)碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。 对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块 从栈中间弹出

    (4)分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成 的,比如局部变量的分配。动态分配由 alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器 进行释放,无需我们手工实现。

    (5)分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈 都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。 

     

     

    5.

    分别描述内存管理要点、autorelease、release、NSAutoreleasePool?并说明autorelease是什 么时候被release的?简述什么时候由你负责释放对象,什么时候不由你释放?

    [NSAutoreleasePool release]和[NSAutoreleasePool drain]有什么区别?

    内存管理要点:

    Objective-C 使用引用计数机制(retainCount)来管理内存。内存每被引用一次,该内存的引用计数+1,每被释放一次引 用计数-1。当引用计数 = 0 的时候,调用该对象的 dealloc 方法,来彻底从内存中删除该对象。 alloc,allocWithZone,new(带初始化)时:该对象引用计数 +1;
    retain:手动为该对象引用计数 +1;

    copy:对象引用计数 +1;
    mutableCopy:生成一个新对象,新对象引用计数为 1;
    release:手动为该对象引用计数 -1; autorelease:把该对象放入自动释放池,当自动释放池释放时,其内的对象引用计数 -1。
    NSAutoreleasePool: NSAutoreleasePool是通过接收对象向它发送的autorelease消息,记录该对象的release消息,当自动释放池被销毁 时,会自动向池中的对象发送release消息。
    autorelease 是在自动释放池被销毁,向池中的对象发送release
    只能释放自己拥有的对象, 区别是:在引用计数环境下(在不使用ARC情况下),两者基本一样,在GC环境下,release 是一个no-op(无效操 作),所以无论是不是gc都使用drain

    6.

    IPhone OS有没有垃圾回收?autorelease 和垃圾回收制(gc)有什么关系?

    答:没有。autorelease只是延迟释放,gc是每隔一段时间询问程序,看是否有无指针指向的对象,若有,就将它回收。他们 两者没有什么关系。

    7.

    为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的? 会引起循环引用----若是retain,在alloc一次之后,若release一次,会导致内存泄漏,若release两次会导致两个 对象的dealloc嵌套执行,结果就是都没有执行成功,最后崩溃! 所有的引用计数系统,都存在循环应用的问题。

    答:例如下面的引用关系:

    * 对象a创建并引用到了对象b.

    * 对象b创建并引用到了对象c.

    * 对象c创建并引用到了对象b.

    这时候b和c的引用计数分别是2和1。 当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。 b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。 这种情况,必须打断循环引用,通过其他规则来维护引用关系。我们常见的delegate往往是assign方式的属性而不是 retain方式 的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。 如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的 delegate又是a,如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用 delegate模式时,也要注意这点。

    8.

    深拷贝和浅拷贝的理解?

    答:对一个实例进行深拷贝时当前类需要实现NSCopying协议。 浅拷贝是复制出来一个跟原对象是同一地址的对象,而深拷贝则是复制出来一个跟源对象不同地址的对象,改变原对象,对新对象没有影响。

     

    9.

    什么是安全释放?

    答:把对象指针置为nil,再对其释放。

    10.

     谈谈你对iOS内存管理的理解

    答:在Objective-C2.0之后引入了垃圾回收机制(GC),但是只是在MAC OS X系统下,iOS下没有垃圾回收。

    Objective-C采用了引用计数的机制来管理对象,引用计数的值表示几个对象在使用它,当对象的引用计数为0的时候,系统负责对象的销毁。可以表述为:1、自己生产的对象(你可以通过alloc(allocWithZone)、new、copy、mutableCopy或者是以这几个单词开头的方法创建对象),自己持有;2、非自己生产的对象,自己也能持有(使用retain);3、不需要持有的对象,自己负责释放(release、autorelease);4、非自己持有的对象,无法释放。内存管理的方式有两种:MRC(手动管理引用计数)和ARC(自动管理引用计数:编译器会在适当的地方插入retain、release、autorelease)。

     11.

    简述OC中内存管理机制

    :1.内存管理分为ARC和MRC两大方面,采用引用计数机制管理内存

    2.MRC方面分为,创造一个对象时会采用allco方法,这时这对象的引用计数为1,我们称为这个对象的对象所有权为1,增加一个对象引用计数的方法还有retain,copy,add等于减少一个对象引用计数的方法为release和autorelease,当一个对象的引用计数减少的方法,使其保持平衡。当一个对象的引用计数为1的时候,我们在调用release或者autorelease的时候,系统会自动调用dealloc方法,释放对象所占资源。

    3.ARC方面,其采用的也是引用计数机制,其原理和MRC一样,只不过把MRC中我们自己管理内存的方式交给了编译器来管理,仍然需要管理内存。

    4.属性修饰词方面:其属性修饰词中和内存有关的,retain,assign,copy,weak,strong其中retain,会使其对象的引用计数加1,assign只是简单的赋值,不会引起引用计数增加,copy分为两种情况:1.深copy会对和浅copy相当于retain,深copy会对copy出来的对象从新开辟一块内存空间,需要对copy出来的对象单独做内存管理。而weak是在ARC中使用的修饰词,其作用相当于assign,但是它有一点比较好的是assign修饰对象为空时,其指针指向nil,防止野指针的出现,strong相当于retain。

  • 相关阅读:
    Guava教程
    Spring Aop基于注解的实现
    简单易懂设计模式——策略模式
    Hibernate入门总结
    mybatis入门详解
    Mybatis【入门总结】
    手把手教你做一个缓存工具
    超简洁!利用easyExcel导出,读入Excel
    飞越面试官(四)--类加载过程
    飞越面试官(三)--JVM
  • 原文地址:https://www.cnblogs.com/jinchengvs/p/4836804.html
Copyright © 2011-2022 走看看