翻译语言

对解释语言的主要关注不是垃圾收集的非确定性延迟(或者当没有足够的延迟时的空间复杂度)吗?所以为什么不直接写一些和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

那么,在这个例子中,除了内存泄漏之外,还有什么需要注意的呢?

9 回复  |  直到 15 年前
    1
  •  20
  •   Norman Ramsey    15 年前

    这个问题背后的前提有点诡异:

    • 记忆模型 语言

    • 被解释是 实施 ,不是语言。

    示例:

    • 编程语言方案具有自动内存管理功能,它有许多解释性实现,但也有一些优秀的本地代码编译器,包括Larceny、Gambit和PLT方案(其中包括 二者都

    • 编程语言Haskell有自动内存管理;最著名的两个实现是解释器HUGS和编译器 GHC . 在编译为本机代码(yhc)和解释(Helium)之间,还有一些其他值得尊敬的实现被平均分配。

    然而,你的问题背后有一个真实的观察: 使用手动内存管理的语言通常是编译的

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

    • 手动内存管理也(有时甚至是合理的)用于提高性能。Ben Zorn在20世纪90年代的出色实验研究表明,自动内存管理的速度和手动内存管理一样快,但需要的内存大约是手动内存管理的两倍。因此,手动内存管理通常用于内存不足的非常小的设备上,而在非常大的数据中心中,加倍内存是昂贵的。(有时也会被不太了解内存管理的人使用,但他们听说垃圾收集很慢。它们在1980年是正确的。)当你担心性能时,你通常会发现一个本地代码编译器而不是一个解释器。

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

    总而言之:

    • 语言 .

    • 编译vs解释是 实施 .

    • 原则上 ,但出于实用的工程原因 .

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

    主要关注编程语言的解释性实现。按字母顺序排列,Lua、Perl、PostScript、Python和Ruby都非常成功,Icon、Scheme和Squeak Smalltalk也相当成功。不可预测的延迟引起关注的唯一领域是硬实时计算,比如控制汽车刹车的ABS系统(如果你驾驶一辆足够豪华的汽车)。


    编辑问题后添加的注释: new delete . 任何语言 新的 删除 有指针:根据定义,无论 返回是指针。(在某些语言中,指针也可能有其他来源。)所以我认为你的意思是“没有指针算术和没有运算符地址的语言”。

        2
  •  4
  •   Doug Currie    15 年前

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

        3
  •  4
  •   Jörg W Mittag    15 年前

    哪些解释语言有手动内存管理?我不记得有过这样的经历。

    世上没有 . 语言既不编译也不解释。一种语言 实施 ,他们有 没有什么 与语言有关。 二者都

    C语言是编译语言吗?外面有C个口译员。Python是一种解释性语言吗?当前的8个Python实现都使用编译器。

    所以,自从 每一个 其实C和C++的解释器就在那里。VxWorks实时操作系统甚至在内核中包含一个权限,NASA曾经使用这个解释器修复航天器上的一个有缺陷的内核模块。)

    另一个例子是从1958年开始的Lisp的第一个版本:它有手动内存管理(基于引用计数),但是仅仅几个月后,它就被替换成了一个自动内存管理的版本,此后它就一直在使用这个版本。尽管如此, 任何 语言既可以用编译器实现,也可以用解释器实现,所以我不知道那个版本是有解释的实现还是编译的实现。(事实上,我不确定它是否被实现了 完全

    如果您稍微放松一下您的标准,并意识到内存管理只是一般资源管理的一个特例,那么您将发现 全部的 语言,不管您是想将它们称为编译的或解释的,还是完全其他的,都至少有某种形式的手动资源管理 一些 资源类型(文件句柄、数据库连接、网络连接、缓存…)。

        4
  •  2
  •   Kornel Kisielewicz    15 年前

    Lua ,可以手动处理垃圾收集。见 lua_gc .

        5
  •  2
  •   Doc Brown    15 年前

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

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

        6
  •  1
  •   Marius    15 年前

    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 ? 将 c类 ?

    你可以阅读其他问题,比如 circular references, on wikipedia .

        7
  •  1
  •   Steve g    15 年前

    不是最担心的 非确定性延迟(或空间 没有足够的复杂性 垃圾收集的延迟?所以为什么 不只是写一些完全一样的东西 Java,但会强制释放内存

    这可能是某些系统的问题。对其他系统来说没什么问题。运行垃圾回收的软件可以比只调用malloc的系统更快地分配内存。当然,你最终会在GC时间支付时间。

    以基于web的系统为例。您可以在处理请求期间分配所有内存,然后GC可以收集。结果可能不是那样的,但你明白了。

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

        8
  •  0
  •   Nikolai Fetissov    15 年前

    解释 并不一定意味着 . Perl、Tcl、Python等,我相信它们都使用简单的引用计数,所以内存回收是确定的,尽管不是透明的(曾经尝试过 strace 在Perl程序上?).

        9
  •  0
  •   jsbueno    15 年前

    Python的API通常允许打开或关闭延迟的垃圾收集-

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

    但与静态语言相比,这并不是导致速度缓慢的原因——数据本身的动态特性是造成速度差异的主要原因。