Języki zarządzane a różnice w języku kompilowanym?

18

Czuję się zagubiony, gdy ludzie próbują rozróżnić języki skompilowane i języki zarządzane. Z doświadczenia rozumiem, że większość uważa skompilowane języki za C, C ++, podczas gdy zarządzanymi językami są Java, C # (Oczywiście jest ich więcej, ale to tylko kilka przykładów). Ale czym dokładnie jest podstawowa różnica między tymi dwoma typami języków?

Rozumiem, że każdy program, niezależnie od używanego języka, jest zasadniczo „kompilowany” w niskopoziomowy kod maszynowy, który jest następnie interpretowany, podobnie jak to czyni z zarządzanych języków podzbiór skompilowanych języków (tzn. Wszystkie zarządzane języki są skompilowane języki, ale nie na odwrót)?

L46kok
źródło
2
termin ten jest ukuty przez Microsoft, w wąskim znaczeniu również Java jest zarządzana. Niemal we wszystkich przypadkach możemy myśleć o zarządzanych językach, takich jak podzbiór tego, który się kompiluje, a także, jak sądzę, jest to powiązane - programmers.stackexchange.com/questions/72446/…
shabunc
Zauważ, że istnieje ogromna różnica między językiem, który kompiluje (statycznie) kod, a czymś, co jest łatwiejsze do zarządzania przez komputer przed uruchomieniem (jak Java), a takim, który robi to w czasie wykonywania (jak Python). Jedną z głównych różnic jest to, że kompilacja statyczna przed uruchomieniem daje komilatorowi szansę na pewne optymalizacje, które mogą skutkować znaczną poprawą prędkości (np. JIT Javy, zmiana kodu dla przewidywania gałęzi itp.).
Shivan Dragon,
6
@ShivanDragon, „język” niczego nie kompiluje. Jego wdrożenie ma. I możesz skompilować Pythona statycznie (patrz na przykład PyPy lub IronPython). OTOH, naprawdę trudno jest to zrobić efektywnie za pomocą dynamicznie wpisywanego języka (patrz „śledzenie JIT”, „abstrakcyjna interpretacja” itp.)
SK-logic
@ SK-logic: zgadzam się, powiedziałem złego ducha. Chciałem nawiązać do platformy, a nie języka.
Shivan Dragon,
@shabunc Właściwie powiedziałbym, że Compiled jest podzbiorem zarządzanych. Język zarządzany może robić wszystko, co może zrobić język skompilowany (praktycznie z tą samą prędkością), a nawet więcej, ponieważ język zarządzany można skompilować. Aby nadać C funkcje języka zarządzanego, musisz zbudować maszynę wirtualną i faktycznie uczynić ją językiem zarządzanym.
Bill K

Odpowiedzi:

47

Różnica nie polega na „skompilowaniu” a „zarządzaniu”, są to dwie osie ortogonalne. Przez „zarządzany” zwykle rozumieją obecność zarządzania pamięcią zebraną w pamięci i / lub obecność infrastruktury maszyny wirtualnej. Oba nie mają absolutnie nic wspólnego z kompilacją i tym, co ludzie uznają za przeciwne.

Wszystkie te „różnice” są dość rozmyte, sztuczne i nieistotne, ponieważ zawsze można łączyć zarządzaną i niezarządzaną pamięć w jednym środowisku wykonawczym, a różnica między kompilacją a interpretacją jest również bardzo niejasna.

Logika SK
źródło
2
Właśnie to miałam na myśli, ale spotkałam wielu ludzi, którzy wciąż robią to rozróżnienie. Dzięki za jasną odpowiedź.
l46kok
Kod zarządzany oznacza posiadanie języka pośredniego, którym należy się zająć w dowolnym środowisku wykonawczym, z którego korzystasz w czasie wykonywania, prawda? Tak więc kompilator musi wygenerować język pośredni (powiedzmy bytecode). IMO, które paruje nieco „zarządzany” kod i „kompilację”. Jednak jeśli język jest „skompilowany”, to nie pokazuje, że daje kod zarządzany (tj. C ++ vs Java)
zgulser
@zgulser, nie, języki pośrednie są ortogonalne. Zarządzany oznacza zintegrowanie GC z językowym środowiskiem wykonawczym. Np. Środowisko uruchomieniowe OCaml jest „zarządzane”, chociaż kompiluje się bezpośrednio do natywnego.
SK-logika
8

Cytując Wikipedię:

Kod zarządzany to termin ukuty przez firmę Microsoft w celu zidentyfikowania kodu źródłowego programu komputerowego, który wymaga i będzie wykonywany tylko w ramach zarządzania maszyną wirtualną Runtime Common Language (w wyniku czego powstaje kod bajtowy).

Kod zarządzany wymaga środowiska wykonawczego (takiego jak .NET CLT) do wykonania.

janvdl
źródło
5
Kod zarządzany nie ma nic wspólnego z frameworkiem. Potrzebuje środowiska wykonawczego zarządzającego pamięcią.
Oded
Być może moje sformułowania są nieco odbiegające od normy, ale czy platforma .NET nie jest tak naprawdę „środowiskiem uruchomieniowym wspólnego języka”?
janvdl,
3
Nie. Zawiera CLR, ale obejmuje także biblioteki klas podstawowych, specyfikację IL i więcej.
Oded
4

Myślę, że należy wprowadzić rozróżnienie, jednak niekoniecznie musi to być „skompilowany” i „zarządzany”. To nie są przeciwieństwa; język może być kompilowany i nie może być zarządzany, lub interpretowany (nieskompilowany) i zarządzany, lub oba, a nawet oba.

„Skompilowany” język to po prostu taki, w którym istnieje krok, który przekształca kod źródłowy napisany przez programistę w bardziej regularny „kod bajtowy”, który jest wykonywany przez maszynę. „Maszyna” może być faktycznym procesorem lub „maszyną wirtualną”, która wykonuje dodatkowe operacje na kodach bajtowych w celu przetłumaczenia ich na „natywne” instrukcje maszyny. Antonimem języka „skompilowanego” jest język „interpretowany”, w którym kod źródłowy jest przetwarzany w instrukcji kodu bajtowego w czasie wykonywania, wiersz po wierszu podczas ich wykonywania, bez kroku kompilacji. Hybrydą między nimi jest „szarpanie”, z „JIT” (Just In Time), co zwykle jest interpretacją jednorazowego kroku wykonywanej maszyny;

Język „zarządzany” to język przeznaczony do tworzenia programów, które są konsumowane w określonym środowisku wykonawczym, które prawie zawsze zawiera interpreter kodu bajtowego; „maszyna wirtualna”, która pobiera kod programu i wykonuje dodatkową transformację specyficzną dla maszyny lub środowiska. Środowisko może również obejmować zarządzanie pamięcią, takie jak „śmieciarz” i inne funkcje „bezpieczeństwa” mające na celu utrzymanie działania programu w „obszarze izolowanym” przestrzeni i narzędzi, jednak takie funkcje nie są wyłączną domeną „zarządzanych” środowisk wykonawczych . Praktycznie wszystkie interpretowane języki można uznać za zarządzane, ponieważ wymagają one, aby interpreter działał pod liniami wykonywanego kodu „użytkownika”. Ponadto języki JVM i .NET (Java, Scala, C #, VB, F #, IronWhthing) są kompilowane do języka pośredniego lub IL, który jest powierzchownie podobny pod względem formy i funkcji do binarnego języka asemblerowego, ale nie przylega w 100% do żadnego „rodzimego” zestawu instrukcji. Instrukcje te są wykonywane przez JVM lub CLR .NET, co skutecznie tłumaczy je na natywne instrukcje binarne specyficzne dla architektury procesora i / lub systemu operacyjnego maszyny.

Tak więc języki można ogólnie opisać jako „skompilowane” lub „zinterpretowane” oraz jako „niezarządzane” (lub „rodzime”) i „zarządzane”. Istnieją języki, które można opisać jako dowolną ich kombinację, z wyjątkiem możliwych „interpretowanych natywnych” (co byłoby prawdą tylko w przypadku odręcznych kodów szesnastkowych, gdzie to, co zostało napisane przez programistę, jest wykonywane); jeśli uznasz warstwę interpretacyjną za „środowisko wykonawcze” (które jest łatwe do argumentowania i trudne do argumentowania), wówczas wszystkie interpretowane języki są „zarządzane”.

Jeśli chcesz uzyskać wiedzę techniczną, prawie wszystkie programy kierowane obecnie na wielozadaniowy system operacyjny są „zarządzane”; system operacyjny utworzy „maszynę wirtualną” dla każdego uruchomionego programu, w którym program myśli (lub przynajmniej nie musi wiedzieć inaczej), że jest to jedyna działająca rzecz. Kod może wywoływać w sobie i do innych bibliotek, do których się odwołuje, tak jakby ten program był jedyną rzeczą załadowaną do pamięci; podobnie wezwania do alokacji pamięci RAM i innej wyższej pamięci do przechowywania danych i manipulowania nimi oraz sterowania urządzeniami są kodowane tak, jakby cała architektura pamięci była dostępna. Maszyna wirtualna (i system operacyjny za nią) następnie tłumaczy różne wskaźniki pamięci na rzeczywistą lokalizację programu, jego danych i przechwytuje sterowniki urządzeń itp. Najczęściej odbywa się to poprzez zastosowanie przesunięcia pamięci (każda maszyna wirtualna otrzymuje blok 2 GB czy cokolwiek z pamięci, zaczynając od adresu X, który program może traktować tak, jakby ten X był adresem 0) i jako taki jest bardzo tani, ale istnieją inne rzeczy, za które odpowiedzialne jest jądro systemu operacyjnego, takie jak planowanie procesów i komunikacja między procesami, które są trudniejsze w zarządzaniu. Jednak ten podstawowy wzorzec na ogół nie jest uważany za „zarządzany”, ponieważ program nie musi wiedzieć, że jest uruchamiany przez maszynę wirtualną i często nadal jest odpowiedzialny za utrzymywanie „przydzielonej” pamięci w czystości. Program, który został zaprojektowany do działania w wierszu poleceń MS-DOS, można uruchomić na nowszych systemach operacyjnych Windows, które nie mają już nawet środowiska MS-DOS; program otrzymuje zamiast tego środowisko „wirtualnej konsoli” i pod warunkiem, że nie próbuje opuścić tego „piaskownicy”

KeithS
źródło
„Języki można ogólnie opisać jako„ skompilowane ”lub„ zinterpretowane ”” - Nie, nie mogą. Kompilacja i tłumaczenie to cechy kompilatorów i tłumaczy, a nie języków. Termin „język skompilowany” nie ma nawet sensu. Gdyby angielski był językiem pisanym, byłby to błąd pisowni.
Jörg W Mittag,
2
Kompilatory i tłumacze zwykle kompilują i interpretują bardzo specyficzne dialekty języków, które zostały zaprojektowane do kompilacji lub tłumaczenia. Nikt nie kompiluje kodu źródłowego JavaScript, który znam, i nikt nie interpretuje C #. Języki są zaprojektowane do używania w taki czy inny sposób. W związku z tym zwykle można nazywać sam język „skompilowanym” lub „zinterpretowanym”, ponieważ pełne środowisko, w którym język jest używany, obejmuje jeden z tych dwóch etapów.
KeithS,
en.wikipedia.org/wiki/Interpreted_language - „Teoretycznie każdy język może być kompilowany lub interpretowany, więc to oznaczenie jest stosowane wyłącznie ze względu na powszechną praktykę implementacyjną, a nie jakąś istotną właściwość języka”.
KeithS,
@KeithS, wikipedia nie jest prawie idealna. Fakt, że artykuł istnieje dla określonego nieważnego terminu, nie powoduje, że termin ten przestaje być ważny. Tak, języki są zawsze projektowane z myślą o określonym sposobie wykonania, ale nadal marnowanie ich jako „skompilowanych” lub „interpretowanych” wyłącznie na podstawie intencji ich projektantów jest bezproduktywne. Jeśli chodzi o interpretację, naprawdę trudno jest znaleźć właściwego „tłumacza” w jakikolwiek sposób. Tcl jest prawdopodobnie ostatnim tego rodzaju. Wszystkie inne tak zwane „tłumacze” są w rzeczywistości kompilatorami.
SK-logic
2

Język zarządzany w prostych słowach jest to język wysokiego poziomu, który zależy od usług udostępnianych przez środowisko wykonawcze, takich jak usługa usuwania śmieci, dlatego jest ogólnie nazywany zarządzany, ale nie jest to jedyna usługa, z której korzysta , a niektóre z tych usług są security services, exception handling, standard typesużywane Common Language Run-time CLRdo uruchamiania, np. w językach .Net lub w środowisku wirtualnym, takim jak Java, które używa JVM Java Virtual Machine.

Język niezarządzany to język niskiego poziomu wykonywalny bezpośrednio przez system operacyjny bez potrzeby korzystania z wirtualnych usług uruchomieniowych lub języka pośredniego, takich jak C, C++niezarządzany kod wytwarzany przez takie języki wykorzystuje procedury biblioteczne, które są dynamicznie połączone z systemem operacyjnym, aby uzyskać kod do wykonania, zwany bibliotekami DLL (Dynamic Link Libraries), niezarządzany kod uzyskuje bezpośredni dostęp do pamięci, dlatego jest szybszy niż kod zarządzany, ale chyba że budujesz sterownik sprzętowy lub zaawansowaną grę wideo, tak naprawdę nie chcesz używać niezarządzanych języków, ponieważ współpraca z niedoświadczonymi programistami, takimi jak stan roli, może być niebezpiecznawith great power comes great responsibilityi dlatego istnieją języki zarządzane, które pomagają programistom w tworzeniu rozszerzalnego kodu bez zanurzania się w system, ale nadal możesz tworzyć mieszany kod, jeśli potrzebujesz, w tych artykułach wyjaśniono wszystko:

Przegląd interoperacyjności zarządzanego / niezarządzanego kodu

Przykład: mieszanie niezarządzanego kodu C ++, C ++ / CLI i C #

Ashraf Abusada
źródło