堆栈溢出和内存泄漏的区别?
堆栈溢出
在Java的内存结构中,堆栈的大小不是无限的。大量的方法调用过程,导致不断的堆栈压入,最终填满堆栈内存,产生StackOv
为什么没有编程语言的内存管理,是手动管理与自动垃圾回收相结合的?
Rust和Objective-C内存管理据bug所知,有两种语言可以做出这种取舍,一种是Rust,一种是OC。但是它基本上不是主流。
Rust通过所有权和生命周期动态管理内存,保证运行时100%的内存安全,需要手动使用时需要用不安全力标记。
Objective-C中有两种内存管理机制:mrc(MannulReferenceCounting)和arc(AutomaticReferenceCounting),分别提供手动和自动内存管理,以满足不同的需求。
主流内存管理和垃圾收集
每种现代语言都有自己的gc处理方法。尽管每种语言都有自己的策略,但它基本上是基于三种基本方法::引文计数、副本收集和标记移除。让让我们逐一介绍。引用计数是一种方便有效的gc管理方法。大多数现代语言都是基于这种方法,包括但不限于python、php、perl、ruby和js。
引用计数的基本原理是程序中的所有对象(比如变量)都有一个全局表来记录它们被引用的次数。释放引用时,计数将减少,直到计数为零,然后释放引用。
引用计数的优点是实现简单,垃圾可以立即回收。缺点是容易形成循环引用,永远不会发布。所以现代语言gc主要是基于引用计数,然后引入一些改进的算法来解决循环引用的问题。
复制收藏
该算法将内存分为两块,其中一块正常使用。当需要gc时,将第一个块中仍在使用的对象复制到另一个块中,然后释放所有第一个内存块。该方法避免了对象存活检查的遍历,提高了效率。
Mark-clear这是最早也是应用最广泛的gc方法,也可以说gc的一般原理就是这种方法。阅卷有两个阶段,阅卷阶段。段需要标记回收的对象;在恢复阶段,有gc统一恢复。
这种方法是有问题的,低效的,并且会产生大量的内存碎片。
事实上,javagc已经集成了2,3个方法,并做了很多其他的改进。可以说javagc是最先进的gc方法。但是由于底层jvm的限制,引用计数法无法使用,所以还是存在一些问题。
业界普遍认为,如果将引用计数与跟踪和回收结合起来,任何GC算法都是最高效和实用的。