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