带手动内存管理的口译语言?

L̲̳*_*̲̳̳ 10 memory interpreter programming-languages memory-management

哪种解释语言无指针语言(IE:Python,Java,Perl,PHP,Ruby,Javascript等)都有手动内存管理?我不记得曾经听过一个.

解释语言的主要问题不是垃圾收集的非确定性延迟(或没有足够延迟时的空间复杂性)吗?那么为什么不写一些与Java完全相同的东西,但强制你手动释放内存?

编辑

我的意思是手动内存管理是语言将引用对象,您可以使用引用删除对象.

例:

Object a = new Object(); // a is a reference to the object
Object b = a; // b is a reference to the same object
a.method(); // fine
delete b; // delete the object referenced by b
a.method(); // null dereference exception
Run Code Online (Sandbox Code Playgroud)

那么有什么警告(除了内存泄漏)可能会出现像这个例子的语言?

Nor*_*sey 20

问题背后的前提有点狡猾:

  • 内存模型是一个性质的语言,而不是它的实现.

  • 被解释为一个的属性实现,而不是语言.

例子:

  • 编程语言方案具有自动内存管理,并且它具有许多几十解释实现的,但也有一些细本机代码的编译器,包括盗窃,开局,和PLT的计划(包括两者的解释和JIT编译器制造的无缝转换).

  • 编程语言Haskell具有自动内存管理功能; 两个最着名的实现是解释器HUGS和编译器GHC.在编译到本机代码(yhc)和解释(Helium)之间,还有其他几个可敬的实现.

  • 编程语言C具有手动内存管理功能,虽然世界上充满了C编译器,但我们这些已经足够记住80年代辉煌的人可能会记住Saber-C或C-terp,它们是MS-DOS的两个非常有用的C语言解释器.

尽管如此,您的问题仍然存在真实的观察结果:通常会编译具有手动内存管理的语言.为什么?

  • 手动内存管理是一项传统功能,通常用于与遗留代码兼容.传统语言通常足够成熟,可以使用本机代码编译器.

  • 许多新语言由实现定义.构建解释器比构建编译器更容易.在解释器中实现简单的自动内存管理比在本机代码编译器中实现高性能自动内存管理更容易.因此,如果语言从其第一个实现中获得定义,则自动内存管理与解释相关联,因为在解释的设置中,实现更容易.

  • 手动内存管理也(有时甚至是合理的)用于提高性能.Ben Zorn在20世纪90年代的优秀实验研究表明,自动内存管理与手动内存管理一样快或快,但需要大约两倍的内存.因此,手动内存管理通常用于内存稀缺的非常小的设备上,而在非常大的数据中心中,内存加倍是昂贵的.(它有时也被那些对内存管理知之甚少的人使用,但是他们听说垃圾收集速度很慢.他们在1980年是正确的.)当有关于性能的问题时,你通常会找到一个本机代码编译器而不是而不是口译员.

    一些非常有趣的例外也来自这个原则.例如,FORTH和第一个PostScript实现都设计为在内存资源稀缺的小型嵌入式设备(望远镜和打印机)上运行,但计算时间不是一个因素.这两种语言最初都是使用比本机代码更紧凑的字节码实现的,并且都具有手动内存管理功能.所以:手动内存管理的解释器.(PostScript的更高版本添加了垃圾收集选项.)

综上所述:

  • 自动与手动内存管理是语言.

  • 编译与解释是实现.

  • 原则上,这两种选择可以是正交的,但是出于实用工程原因,自动存储器管理经常与解释相关联.

解释语言的主要问题不是垃圾收集的非确定性延迟(或没有足够延迟时的空间复杂性)吗?

我不知道有关于编程语言的解释实现一个主要问题.按字母顺序排列,Lua,Perl,PostScript,Python和Ruby都非常成功,Icon,Scheme和Squeak Smalltalk都取得了一定的成功.不可预知的延迟引起关注的唯一区域是硬实时计算,例如控制汽车制动器的ABS系统(如果你驾驶的汽车足够花哨).


在编辑问题后添加注释:您将"解释"更改为"无指针".但是你在评论中说,你的意思是询问new和语言delete.用任何语言newdelete具有指针:顾名思义,无论new返回一个指针.(在某些语言中,也可能有其他指针源.)所以我认为你的意思是"没有指针算术且没有地址操作符的语言".


Dou*_*rie 5

Forth具有可以使用 FORGET 释放的堆叠内存区域。


Mar*_*ius 1

原因是循环引用、空指针异常和多重引用。一个简单的例子:

var a = new Object();
var b = a;
a = null;//or delete a or free a or whatever;
print(b);//what now? is b null? or is b still new Object()?
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,如果b现在为 null,则在重新定义变量时最终会遇到一些主要问题。例如,如果将其设置为a,而不是设置为 null 会怎样c?也会bc

您可以在维基百科上阅读有关其他问题的信息,例如循环引用