10

其中 解释语言 无指针语言(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 

那么什么注意事项(除内存泄漏)莫不是在这样的例子一门语言?

+0

btw,你这里的“解释”是什么意思? Java在字节码的这些日子里与Python,PHP或Javascript一样被“解释”。也许你会更准确地提到“动态类型”的语言? – jsbueno 2010-01-25 17:31:49

+0

解释器执行的任何东西,无论是中间形式还是普通字节码。特别是像php/java/perl/python/ruby​​这样的东西不会让你垃圾地址空间。 – 2010-01-25 17:34:26

+1

C#不是无指针的。 – 2010-01-26 14:16:15

回答

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()? 

如果在上面的例子中,b现在是零,你重新定义变量的时候结束了一些重大问题。例如,而不是将a设置为空,如果将其设置为c,会发生什么情况? b也是c

您可以阅读其他问题,如circular references, on wikipedia

+0

循环引用问题可以通过基于区域的内存管理来解决。早期的手动方法是竞技场和基于堆栈的内存管理,如Forth的FORGET。 – 2010-01-25 17:07:14

+0

是空引用本来是好的,但我没有考虑引用别名,这使事情变得复杂。 – 2010-01-25 17:23:13

0

解读并不一定意味着垃圾收集。 Perl,Tcl,Python等等。我相信所有的程序都使用简单的引用计数,所以内存回收是确定性的,尽管不是完全透明的(曾经在Perl程序上试过strace?)。

+0

引用计数是垃圾收集的一种类型,尽管它的失败经常使用,因为它很容易实现并且不依赖于平台。 – 2010-01-25 17:09:01

+0

是的,但这只是术语。我的意思是内嵌的ref-counting与GC/in-the-the-background在Java/C#中的背景。 – 2010-01-25 17:11:45

+0

是的,我知道Python没有引用计数。我正在讨论显式删除对象,以便通过两个引用来访问对象时,通过一个引用进行两次引用并删除将产生异常。 – 2010-01-25 17:26:38

2

在某些高性能解释语言(如Lua)中,您可以手动处理垃圾回收。见lua_gc

4

Forth堆叠了可以用FORGET释放的内存区域。

2

有一些C/C++解释器可用,例如this one

没有自己尝试过,但我认为,因为它声称与编译的C/C++兼容,它需要有“手动”内存管理。

0

Python的API oficially允许一个打开或关闭延迟的垃圾收集 - 检查文档标准库的“GC”模块:

http://docs.python.org/library/gc.html

但是,这并不是什么使得它缓慢当与静态语言相比时 - 数据本身的动态特性是负责速度差异的主要因素。

1

所以回答这个问题的这一部分:垃圾

不是主要关切 解释语言 非确定性延迟(或空间 复杂性时没有足够的 延迟)采集?那么为什么 不只是写一些类似于 Java的东西,而是强制你手动释放内存 ?

这可能是一些系统的问题。对其他系统来说不是一个问题。运行垃圾回收的软件可以比调用malloc的系统更快地分配内存。当然,你最终在GC时间后付款。

以网络系统为例。您可以在处理请求期间分配所有内存,然后GC可以收集。最终可能不会像这样做,但你明白了。

有很多不同的垃圾收集策略。哪种策略最适合系统将取决于要求。但即使您需要绝对确定性,您也可以使用类似的方法:Realtime Java

3

哪些解释语言具有手动内存管理?我不记得曾经听过一个。

有没有这样的事情解释语言。一种语言既不被编译也不被解释。一种语言。语言是一堆抽象的数学规则。口译或汇编是一种语言的特征执行,他们有没有与语言。 每个语言都可以由编译器或解释器来实现;大多数现代高性能语言的实现实际上都使用,并且在它们之间切换取决于哪个在特定上下文中更快。

C是一种编译语言吗?那里有C口译员。 Python是一种解释型语言吗?目前所有8种Python实现都使用编译器。

因此,由于语言可以有一个解释实现,C和C + +是手动内存管理的解释语言的示例。 (这不仅仅是一个理论上的分拆比赛,实际上有C和C++解释器在这里,,VxWorks实时操作系统甚至在内核中包含一个权利,NASA曾经使用这个解释器来修复一辆越野车内核模块)

另一个例子是1958年Lisp的第一个版本:它具有手动内存管理(基于引用计数),但它仅在几个月后被一个版本替换自动存储器管理,它自那以后使用。虽然任何语言可以用编译器或解释器来实现,所以我不知道该版本是否有解释的实现或编译的实现。 (事实上​​,我不确定它是否实施在所有。)

如果你放松你的标准一点点,认识到内存管理也只是一般资源管理的一种特殊情况,那么你会发现,几乎所有语言,无论你想打电话给他们编译或解释或完全不同的是,至少有一些形式的资源管理(文件句柄,数据库连接,网络连接,缓存......)。

+0

我认为解释他只是指脚本,就像Python,Perl等......你是对的,但这是提出这个讨论= P的错误地方。 – Claudiu 2010-01-26 00:36:40

+0

确实你是对的,但这与我的问题意味着什么没有关系。我会试着更加具体地解释我的解释型语言的含义:“不像C/C++那样接近金属的内存安全(不一定是”script-ish“)语言,它们不会让你丢弃你的地址空间,除非你真的想要;最常用JIT编译和/或解释的语言(和/或甚至在该过程之前编译成字节码(并且或者提前编译))。“ – 2010-01-26 01:18:03

18

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

  • 内存模型语言的属性,而不是它的实现。

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

例子:

  • 编程语言方案具有自动内存管理,它有很多几十解释实现的,但也有一些细微的本地代码编译器,包括盗窃,开局和PLT计划(其中包括均为解释器和JIT编译器进行无缝转换)。

  • 编程语言Haskell具有自动内存管理功能;最着名的两个实现是解释器HUGS和编译器GHC。在编译为本地代码(yhc)和解释(氦气)之间还有几个其他的荣誉实现可以平均分配。编程语言C具有手动内存管理,尽管世界充满了C编译器,但我们这些年龄足以记住20世纪辉煌的人可能还记得Saber-C或C-terp,这是两种非常有用的C解释器, MS-DOS。

不过有你的问题背后一个真实的观察:语言与手动内存管理通常被编译。为什么?

  • 手动内存管理是一项传统功能,通常用于与旧代码兼容。传统语言通常足够成熟,可以拥有本地代码编译器。

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

  • 手动内存管理也有时(甚至有理由)用于提高性能。 Ben Zorn在20世纪90年代出色的实验研究表明,自动内存管理与手动内存管理相比速度更快或更快,但需要的内存大约是内存的两倍。所以手动内存管理通常用在内存稀少的非常小的设备上,以及在非常大的数据中心内部,内存翻倍是昂贵的。 (有时也被那些不太了解内存管理的人使用,但有人听说垃圾收集速度很慢,他们在1980年是对的)。当性能问题出现时,通常会发现一个本地代码编译器而不是口译员。

    一些非常有趣的例外也来自这个原则。例如,FORTH和第一个PostScript实现都设计为在小型嵌入式设备(望远镜和打印机)上运行,这些设备的内存资源很少,但计算时间并不是一个因素。两种语言都首先使用比本地代码更紧凑的字节码来实现,并且都使用手动内存管理。所以:手动内存管理的口译员。 (后来的版本的PostScript增加了垃圾收集的选项。)

总结:

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

  • 编译vs解释是执行

  • 原则两个选项可以和正交制造,但对于务实的工程原因自动内存管理经常与解释相关。

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

我不知道有关于编程语言的解释实现的主要关注。按照字母顺序,Lua,Perl,PostScript,Python和Ruby都非常成功,而Icon,Scheme和Squeak Smalltalk则相当成功。难以预料的延迟引起担忧的唯一领域是硬实时计算,如控制汽车刹车的ABS系统(如果您驾驶的是一辆足够豪华的汽车)。


注意补充问题进行修改后:你变了“解释”为“无指针”。但是你在评论中说,你的意思是询问有关newdelete的语言。带有newdelete的任何语言都有指针:根据定义,无论new返回的是什么指针。 (在某些语言中,也可能有其他指针来源。)所以我认为你的意思是说“没有指针算术的语言,没有一个操作符的地址”。

+0

像'new'和'delete'运算符一样的手动内存管理。尝试解引用'delete'd对象将导致异常或某种其他错误,而不是未定义的行为。根据我的示例,基本上与Java相同,但带有删除操作符。尽管如此,你还是有一个关于手动内存管理的好处。 – 2010-01-26 03:33:53