2009-11-06 37 views
10

我知道GC是不是在天流行時,阿達的開發和嵌入式編程的主要使用情況下,它仍然不是一個很好的選擇。爲什麼Ada沒有垃圾收集器?

但考慮到小梅是一種通用的編程語言,爲什麼沒有一個部分和可選的(僅跟蹤顯式標籤的內存對象)垃圾收集器在語言的更新版本和編譯器實現引入。

我簡直無法想象開發一個沒有垃圾回收器的普通桌面應用程序了。

+4

問題有點錯了,因爲說,因爲一些*做*有GC,這是任何編譯器作者提供的選項。我當然希望在Ada上搜索的人不會遇到這個問題,並認爲Ada會阻止GC。 – 2009-11-11 23:54:51

+0

這不是一種通用的編程語言。它僅爲美國國防部項目設計和授權。非常獨特的部門。 – EJP 2015-07-29 08:50:09

回答

30

阿達在設計時考慮到軍事領域。其設計的重點之一是決定論。即有人希望Ada程序能夠在任何環境下,每次在任何操作系統下始終以完全相同的方式執行相同的操作......這種事情。

垃圾收集器將一個應用程序變成兩個,互相作用。 Java程序開發在隨機時間間隔打嗝時,GC決定去工作,如果它是關於它太慢有一個機會,一個應用程序將用盡堆有時而不是其他人。

簡化:垃圾回收器將一些可變性引入到設計人員不想要的程序中。你弄得一團糟 - 你清理它!相同的代碼,每次都有相同的行爲。

不是說Ada成爲了一個洶涌的世界範圍的成功,請關注你。

+0

好吧,但是爲什麼Ada在2種主要語言修訂後仍然沒有垃圾收集器。甚至沒有可選的一個? C++沒有得到它只有一個原因 - 沒有足夠的時間正確地指定的東西。 – Lothar 2009-11-07 00:52:58

+4

語言中沒有任何內容表示「沒有垃圾回收器」,正如你所暗示的那樣。如果有人想在他們的編譯器中使用某個編譯器,他們可以自由地將其放入。一些編譯器有。 – 2009-11-11 23:52:37

+1

對不起,這個答案是完全錯誤的,例如,在艾達的任務模式的大段非determistic。 沒有什麼在Ada語言規範,防止GC - 有GC上的可選包添加如果你想他們。 – YermoungDer 2009-12-01 14:14:24

12

因爲艾達被設計用於在控制武器的實時防禦系統的使用,和垃圾收集與應用程序的時間干擾。這是很危險的,這就是爲什麼多年來,Java帶來了一個警告,那就是它不能用於醫療和軍事控制系統。

我相信再也沒有與Java這樣的聲明的原因是因爲底層的硬件已經變得更快,以及作爲Java有更好的GC算法和GC上更好地控制這一事實。

記住,艾達是在1970年和1980年的一次開發時,電腦是遠遠不那麼強大的比今天和控制應用的時序問題是最重要的。

+0

我還要補充的航空機載軟件:沒有人願意自動駕駛4秒時只是凍結,因爲垃圾收集在試圖降落。 大多數嵌入式計算機的CPU,內存都比您的智能手機少:內存和調度控制不是一個選項,它是強制性的。 – LoneWanderer 2017-03-12 18:05:05

4

答案比較複雜:Ada不需要垃圾收集器,因爲實時限制等原因。然而,這種語言的設計非常巧妙,可以實現垃圾收集器。

雖然,許多(幾乎所有)的編譯器不包括垃圾收集器,也有一些顯着的實現:

  • a patch for GNAT
  • Ada編譯針對Java虛擬機(我不知道如果這些項目仍然受支持)。它使用了JVM的垃圾收集器。

大約有垃圾收集阿達各地的網絡大量的其他來源。這個問題已經被詳細討論過了,主要是因爲在微軟吸引C#之前,Java是「下一件大事」時,與Java在90年代中期的激烈競爭(看看this page"Ada 95 is what the Java language should have been")。

3

首先,沒有什麼語言真的禁止垃圾收集。

其次某些實現確實執行垃圾回收。特別是,所有以JVM垃圾收集爲目標的實現。

第三,有一種方法可以獲得一定數量的垃圾回收與所有編譯器。你會發現,當訪問類型超出範圍時,如果特定地告訴語言留出一定數量的空間用於存儲其對象,那麼該空間將在此時被銷燬。我過去曾使用過這個技術來獲得一些垃圾收集。 voodo您使用的聲明是:

type Foo is access Blah; 
for Foo'storage_size use 100_000_000; --// 100K 

如果你這樣做,然後分配給布拉赫對象的內存中的所有(100K)指向指針富時富類型超出範圍將被清理。由於Ada允許您在其他子例程中嵌套子例程,所以這特別強大。

要了解更多關於STORAGE_SIZE和存儲池可以爲你做什麼,看到LRM 13.11

第四,精心編寫的Ada程序不傾向於依靠動態內存分配遠遠不如C程序做。 C有許多設計漏洞,實踐者學會了使用指針來繪製。很多這些成語在Ada中並不是祕密。

0

首先,我想知道誰最近在使用Ada。我真的很喜歡這種語言,甚至還有一個Linux/Ada的GUI庫,但是我多年來一直沒有聽說過有關Ada的積極開發的事情。由於它的軍事聯繫,我真的不確定這是古老的歷史還是非常成功,所有提及它的使用都被歸類。

我想在Ada中沒有GC的原因有兩個。首先,最重要的是,它可以追溯到大多數編譯語言主要用於堆棧或靜態內存的時代,或者在少數情況下,顯式堆分配/釋放。作爲一般哲學的GC實際上只是在1990年左右纔開始起飛,當OOP改進了內存管理算法和處理器的強大功能,足以讓這些週期運行起來的時候,它們全都出現了。簡單地編譯Ada在1989年對IBM 4331主機的做法簡直是無情。現在我的手機可以勝過該機器的CPU。

另一個很好的理由是,有人認爲嚴格的程序設計包括對內存資源的精確控制,並且不應該讓動態獲取的對象浮動。可悲的是,隨着動態記憶逐漸成爲越來越多的規則,很多人最終都在泄漏記憶。另外,就像彙編語言在高級語言上的「效率」和ORM系統上原始JDBC的「效率」一樣,手動內存管理的「效率」往往會隨着它的擴展而反轉(我見過ORM基準測試JDBC等價物的效率只有一半)。我知道,與直覺相反,但現在系統在全局優化大型應用程序方面要好得多,而且它們能夠根據表面上的小變化進行根本性的重新優化。包括基於檢測到的動態重新動態平衡算法加載。

恐怕我不得不與那些說實時系統無法負擔GC內存的人不同。 GC不再是每隔幾分鐘就凍結整個系統的東西。這些日子我們有更聰明的方式來回收記憶。

+0

好吧,有一個正在開發的Ada標準的新版本,正在積極開發中。 GCC Ada編譯器也在積極開發。 – 2009-11-12 14:47:35

+2

我認爲你在第三段中提到了一些東西。 Ada絕對是一種能夠控制怪胎的語言。如果你願意的話,你可以進入並告訴編譯器精確的記錄類型中的每個字段使用哪些偏移量和哪些位。你甚至不能用C來做這件事。喜歡這種事情的人不容易成爲懶散的動態內存使用實踐的粉絲。 – 2009-11-12 14:50:57

+0

我會添加第三個評論的樂趣。你最後一段讓我好奇,所以我去看了看。在我看來,仍然沒有任何*確定性*一般的GC算法可用。有一些人試圖通過限制一次完成的工作量來僞造它,但這隻會給你一個可能落後的GC(最終讓你失去內存)。 – 2011-02-07 15:03:20

-1

你的問題是不正確的。它的確如此。查看爲您處理GC的軟件包ada.finalization。

+0

這實際上更像是一種提供RAII的方法,就像您可以使用典型的C++類一樣。如果你想用它來分配在Ada類中的GC東西,你必須寫(正確的!)來做到這一點。它與Java對編譯器所要求的一般無腦GC不太一樣。但是,我相信所有針對JVM(Java虛擬機)的Ada編譯器都使用它的垃圾收集。 – 2010-10-19 13:19:29

0

我想我會分享如何實現自由()過程(這將在大家都熟悉的C語言編程的方式來使用),一個非常簡單的例子...

with Ada.Integer_Text_IO, Ada.Unchecked_Deallocation; 
use Ada.Integer_Text_IO; 

procedure Leak is 
    type Int_Ptr is access Integer; 
    procedure Free is new Ada.Unchecked_Deallocation (Integer, Int_Ptr); 

    Ptr : Int_Ptr := null; 
begin 
    Ptr := new Integer'(123); 
    Free (Ptr); 
end Leak; 

調用free在程序結束時會將分配的Integer返回到存儲池(C語言中的「堆」)。您可以使用valgrind來證明這確實可以防止4個字節的內存泄漏。

的Ada.Unchecked_Deallocation(一般定義的過程)可以在(我認爲),其可以使用「新」的關鍵字被分配任何類型的使用。 Ada參考手冊(「13.11.2未檢查的存儲釋放」)有更多細節。