ภาษาที่จัดการกับความแตกต่างของภาษาที่รวบรวมหรือไม่


18

ฉันสับสนเมื่อผู้คนพยายามสร้างความแตกต่างระหว่างภาษาที่รวบรวมและภาษาที่มีการจัดการ จากประสบการณ์ฉันเข้าใจว่าส่วนใหญ่พิจารณาภาษาที่คอมไพล์เป็น C, C ++ ในขณะที่ภาษาที่ได้รับการจัดการคือ Java, C # (มีอีกมากที่เห็นได้ชัด แต่นี่เป็นเพียงตัวอย่างเล็ก ๆ น้อย ๆ ) แต่ความแตกต่างหลักระหว่างภาษาสองประเภทคืออะไร?

ความเข้าใจของฉันคือว่าโปรแกรมใด ๆ ไม่ว่าภาษาใดที่คุณใช้จะถูก "รวบรวม" เป็นรหัสเครื่องในระดับต่ำซึ่งจะถูกตีความแล้วดังนั้นจึงทำให้ภาษาที่ได้รับการจัดการเป็นส่วนย่อยของภาษาที่รวบรวม (นั่นคือภาษาที่มีการจัดการทั้งหมด ภาษาที่คอมไพล์ แต่ไม่ใช่วิธีอื่น ๆ )


2
คำนี้ประกาศเกียรติคุณจาก Microsoft ในแง่แคบ Java มีการจัดการเช่นกัน เกือบทุกกรณีเราสามารถนึกถึงภาษาที่ได้รับการจัดการเหมือนกับชุดย่อยของภาษานั้นที่รวบรวมได้นอกจากนี้ฉันเชื่อว่ามีความเกี่ยวข้อง - programmers.stackexchange.com/questions/72446/ …
shabunc

โปรดทราบว่ามีความแตกต่างอย่างมากระหว่างภาษาที่รวบรวม (แบบคงที่) โค้ดกับสิ่งที่จัดการได้มากกว่าเครื่องก่อนรันไทม์ (เช่น Java) และภาษาที่ใช้ในขณะรันไทม์ (เช่น Python) ข้อแตกต่างที่สำคัญอย่างหนึ่งก็คือการรวบรวมแบบสแตติกก่อนรันไทม์ทำให้ comiler มีโอกาสเพิ่มประสิทธิภาพบางอย่างซึ่งอาจส่งผลให้มีการปรับปรุงความเร็วสูง (เช่น JIT ของ Java การจัดเรียงโค้ดสำหรับการคาดการณ์สาขาเป็นต้น)
Shivan Dragon

6
@ShivanDragon "ภาษา" ไม่ได้รวบรวมอะไรเลย การใช้งานไม่ และคุณสามารถคอมไพล์ Python แบบสแตติก (ดู PyPy หรือ IronPython) OTOH มันยากมากที่จะทำอย่างมีประสิทธิภาพด้วยภาษาที่พิมพ์แบบไดนามิก (ค้นหา "การติดตาม JIT", "การตีความเชิงนามธรรม" ฯลฯ )
SK-logic

@ SK-logic: เห็นด้วยฉันพูด baddie ฉันต้องการอ้างถึงแพลตฟอร์มไม่ใช่ภาษา
Shivan Dragon

@shabunc ที่จริงฉันจะบอกว่าคอมไฟล์เป็นส่วนย่อยของ Managed ภาษาที่มีการจัดการสามารถทำทุกสิ่งที่ภาษาที่คอมไพล์สามารถทำได้ (ที่ความเร็วเท่ากันจริง) และมากกว่านั้นเนื่องจากภาษาที่มีการจัดการสามารถรวบรวมได้ ในการให้คุณสมบัติ C ของภาษาที่มีการจัดการคุณต้องสร้าง "VM" และทำให้เป็นภาษาที่ได้รับการจัดการจริง
Bill K

คำตอบ:


47

ความแตกต่างไม่ได้อยู่ใน "เรียบเรียง" กับ "จัดการ" นี่คือแกนตั้งฉากสองแกน โดย "จัดการ" พวกเขามักจะหมายถึงการปรากฏตัวของการจัดการหน่วยความจำเก็บขยะและ / หรือการปรากฏตัวของโครงสร้างพื้นฐานเครื่องเสมือน ทั้งสองไม่มีอะไรเกี่ยวข้องกับการรวบรวมและสิ่งที่ผู้คนคิดว่าจะตรงข้ามกับมัน

"ความแตกต่าง" ทั้งหมดนี้ค่อนข้างเบลอประดิษฐ์และไม่เกี่ยวข้องเนื่องจากเป็นไปได้ที่จะผสมผสานหน่วยความจำที่มีการจัดการและไม่มีการจัดการในรันไทม์เดียวและความแตกต่างระหว่างการรวบรวมและการตีความก็ไม่ชัดเจนเช่นกัน


2
นี่คือสิ่งที่ฉันมีอยู่ในใจ แต่ฉันเจอคนจำนวนมากที่ทำให้ความแตกต่างนี้ ขอบคุณสำหรับคำตอบที่ชัดเจน
l46kok

รหัสที่มีการจัดการหมายถึงการมีภาษาระดับกลางที่จะดูแลสิ่งที่สภาพแวดล้อมการดำเนินการที่คุณกำลังทำงานอยู่ที่รันไทม์ใช่มั้ย ดังนั้นภาษากลาง (สมมติว่า bytecode) จะต้องมีการผลิตโดยคอมไพเลอร์ IMO ซึ่งเป็นแนวคิดที่ "จัดการ" รหัสและ "รวบรวม" แนวคิดเล็กน้อย อย่างไรก็ตามหากภาษานั้น "คอมไพล์" นั่นจะไม่แสดงว่ามันเป็นรหัสที่ได้รับการจัดการ (เช่น C ++ กับ Java)
zgulser

@zgulser ไม่ภาษากลางเป็นมุมฉาก การจัดการหมายถึงการมี GC รวมกับรันไทม์ภาษา เช่น OCaml runtime เป็น "จัดการ" แม้ว่ามันจะรวบรวมตรงไปยังพื้นเมือง
SK-logic

8

ในการอ้างถึง Wikipedia:

Managed code เป็นคำประกาศเกียรติคุณจาก Microsoft เพื่อระบุซอร์สโค้ดโปรแกรมคอมพิวเตอร์ที่ต้องการและจะดำเนินการภายใต้การจัดการของเครื่องเสมือนภาษา Common Language Runtime เท่านั้น (ส่งผลให้เกิดเป็นไบต์)

รหัสที่มีการจัดการต้องการรันไทม์ (เช่น. NET CLT) เพื่อดำเนินการ


5
รหัสที่ได้รับการจัดการไม่มีส่วนเกี่ยวข้องกับกรอบงาน มันต้องการรันไทม์ที่จัดการหน่วยความจำ
Oded

บางทีถ้อยคำของฉันอาจปิดไปบ้าง แต่กรอบงาน. NET ไม่ใช่ "การใช้งานจริงของภาษาทั่วไป" ใช่หรือไม่
janvdl

3
ไม่ได้รวมถึง CLR แต่ยังรวมถึงไลบรารีคลาสพื้นฐานข้อมูลจำเพาะของ IL และอื่น ๆ
Oded

4

ฉันคิดว่ามีความแตกต่างที่จะทำ แต่ไม่จำเป็นระหว่าง "รวบรวม" และ "จัดการ" สิ่งเหล่านี้ไม่ตรงข้าม ภาษาที่สามารถรวบรวมและไม่ได้รับการจัดการหรือตีความ (ไม่ได้รวบรวม) และมีการจัดการหรือทั้งสองอย่างหรือแม้กระทั่งทั้งไม่

ภาษา "เรียบเรียง" เป็นเพียงภาษาเดียวที่มีขั้นตอนในการแปลงซอร์สโค้ดที่นักพัฒนาเขียนไปเป็น "bytecode" ซึ่งเป็นสิ่งปกติที่ดำเนินการโดยเครื่อง "machine" อาจเป็นโปรเซสเซอร์จริงหรือ "virtual machine" ที่ดำเนินการเพิ่มเติมในไบต์เพื่อแปลให้เป็นคำสั่งของเครื่อง "native" คำตรงข้ามสำหรับภาษา "รวบรวม" เป็นภาษา "ตีความ" ซึ่งรหัสแหล่งที่มาจะถูกแปลงเป็นคำแนะนำ bytecode ที่รันไทม์ทีละบรรทัดตามที่พวกเขาจะถูกดำเนินการโดยไม่มีขั้นตอนการรวบรวม ไฮบริดระหว่างพวกเขาคือ "jitting" จาก "JIT" (Just In Time) ซึ่งมักจะตีความว่าเป็นขั้นตอนเดียวโดยเครื่องที่ดำเนินการ

ภาษา "ที่ได้รับการจัดการ" เป็นภาษาที่ออกแบบมาเพื่อผลิตโปรแกรมที่ใช้งานในสภาพแวดล้อมรันไทม์เฉพาะซึ่งมักจะมีล่าม bytecode; "เครื่องเสมือน" ที่ใช้รหัสของโปรแกรมและทำการแปลงเครื่องเพิ่มเติมหรือการแปลงสภาพแวดล้อมเฉพาะ สภาพแวดล้อมอาจรวมถึงการจัดการหน่วยความจำเช่นคุณสมบัติ "ตัวรวบรวมขยะ" และ "ความปลอดภัย" อื่น ๆ ที่มีความหมายเพื่อให้โปรแกรมทำงานภายใน "แซนด์บ็อกซ์" ของพื้นที่และเครื่องมืออย่างไรก็ตามคุณลักษณะดังกล่าวไม่ใช่โดเมนเพียงอย่างเดียวของ . ภาษาที่ตีความทั้งหมดอาจถูกพิจารณาว่ามีการจัดการเพราะพวกเขาต้องการล่ามที่จะทำงานภายใต้บรรทัดของรหัส "ผู้ใช้" ที่กำลังดำเนินการ นอกจากนี้ภาษา JVM และ. NET (Java, Scala, C #, VB, F #, IronWhething) ถูกรวบรวมเป็นภาษาระดับกลางหรือ IL ซึ่งมีความคล้ายคลึงอย่างผิวเผินในรูปแบบและฟังก์ชั่นกับภาษาแอสเซมบลีไบนารี แต่ไม่ได้ยึด 100% กับชุดคำสั่ง "ดั้งเดิม" ใด ๆ คำแนะนำเหล่านี้ดำเนินการโดย JVM หรือโดย CLR ของ. NET ซึ่งแปลได้อย่างมีประสิทธิภาพเป็นคำสั่งไบนารีดั้งเดิมที่เฉพาะเจาะจงกับสถาปัตยกรรม CPU และ / หรือ OS ของเครื่อง

ดังนั้นภาษาโดยทั่วไปสามารถอธิบายได้ว่า "รวบรวม" หรือ "ตีความ" และเป็น "ไม่มีการจัดการ" (หรือ "ดั้งเดิม") และ "จัดการ" มีภาษาที่สามารถอธิบายได้ว่าเป็นการรวมกันของสิ่งเหล่านี้ยกเว้น "การตีความดั้งเดิม" ที่เป็นไปได้ (ซึ่งจะเป็นจริงสำหรับ opcodes เลขฐานสิบหกที่เขียนด้วยมือซึ่งสิ่งที่เขียนโดยนักพัฒนาคือสิ่งที่ถูกดำเนินการ) หากคุณพิจารณาเลเยอร์การตีความว่าเป็น "รันไทม์" (ซึ่งเป็นเรื่องง่ายที่จะโต้แย้งและยากที่จะโต้แย้ง) ภาษาที่ตีความทั้งหมดจะ "จัดการ"

หากคุณต้องการได้รับเทคนิคเกือบทุกโปรแกรมที่กำหนดเป้าหมายระบบปฏิบัติการมัลติทาสกิ้งทุกวันนี้จะ "จัดการ"; ระบบปฏิบัติการจะสร้าง "เครื่องเสมือน" สำหรับแต่ละโปรแกรมที่กำลังทำงานซึ่งโปรแกรมคิดว่า (หรืออย่างน้อยก็ไม่จำเป็นต้องรู้อย่างอื่น) ว่ามันเป็นสิ่งเดียวที่ทำงานอยู่ รหัสอาจทำการโทรภายในตัวเองและไปยังไลบรารีที่อ้างอิงอื่น ๆ ราวกับว่าโปรแกรมนั้นเป็นสิ่งเดียวที่โหลดในหน่วยความจำ ในทำนองเดียวกันการโทรเพื่อจัดสรร RAM และหน่วยความจำที่สูงกว่าอื่น ๆ เพื่อจัดเก็บและจัดการข้อมูลและอุปกรณ์ควบคุมจะถูกเข้ารหัสราวกับว่าสถาปัตยกรรมหน่วยความจำทั้งหมดพร้อมใช้งาน VM (และระบบปฏิบัติการด้านหลัง) จากนั้นแปลพอยน์เตอร์ของหน่วยความจำต่าง ๆ ไปยังตำแหน่งที่แท้จริงของโปรแกรม, ข้อมูล, และ hooks ไปยังไดรเวอร์อุปกรณ์เป็นต้นซึ่งมักทำโดยใช้ออฟเซ็ตหน่วยความจำ (VM แต่ละตัวรับบล็อก 2GB หรืออะไรก็ตามที่จำ เริ่มต้นที่ address X ซึ่งโปรแกรมสามารถจัดการได้ราวกับว่า X เป็นแอดเดรส 0) และเป็นสิ่งที่ถูกมากที่ต้องทำ แต่มีสิ่งอื่น ๆ ที่เคอร์เนล OS รับผิดชอบเช่นการกำหนดตารางกระบวนการและการสื่อสารระหว่างกระบวนการซึ่งเป็น เคล็ดลับในการจัดการ อย่างไรก็ตามรูปแบบพื้นฐานนี้โดยทั่วไปจะไม่ถือว่าเป็น "จัดการ" เนื่องจากโปรแกรมไม่จำเป็นต้องรู้ว่ามันถูกเรียกใช้โดยเครื่องเสมือนและมักจะยังคงรับผิดชอบการรักษาหน่วยความจำที่จัดสรร "สะอาด" โปรแกรมที่ออกแบบมาให้ทำงานบนบรรทัดคำสั่ง MS-DOS สามารถเรียกใช้บนระบบปฏิบัติการ Windows รุ่นใหม่ที่ไม่มีสภาพแวดล้อม MS-DOS ที่อยู่ภายใต้อีกต่อไป โปรแกรมได้รับสภาพแวดล้อม "virtual console" แทนและหากไม่พยายามออกจาก "sandbox" นี้


"ภาษาทั่วไปสามารถอธิบายได้ว่า" รวบรวม "หรือ" ตีความ "" - ไม่พวกเขาไม่สามารถ การรวบรวมและการตีความเป็นลักษณะของดีรวบรวมและล่ามไม่ใช่ภาษา คำว่า "ภาษารวบรวม" ไม่ได้ทำให้รู้สึก หากภาษาอังกฤษเป็นภาษาที่พิมพ์แล้วมันจะเป็นข้อผิดพลาดประเภท
Jörg W Mittag

2
คอมไพเลอร์และล่ามมักจะพบการรวบรวมและล่ามภาษาเฉพาะของภาษาที่ออกแบบมาเพื่อรวบรวมหรือตีความ ไม่มีการคอมไพล์ซอร์สโค้ด JavaScript ที่ฉันรู้จักและไม่มีการตีความ C # ภาษาได้รับการออกแบบมาเพื่อการบริโภคในทางเดียวหรืออื่น ๆ ในฐานะที่เป็นเช่นนี้ก็คือมักจะได้รับการยอมรับในการอ้างถึงภาษาที่ตัวเองเป็น "รวบรวม" หรือ "ตีความ" เพราะสภาพแวดล้อมที่เต็มซึ่งเป็นภาษาที่ถูกนำมาใช้ที่เกี่ยวข้องกับหนึ่งในบรรดาสองขั้นตอน
KeithS


en.wikipedia.org/wiki/Interpreted_language - "ในทางทฤษฎีภาษาใด ๆ ที่อาจจะรวบรวมหรือตีความดังนั้นการกำหนดนี้จะถูกนำไปใช้อย่างหมดจดเพราะการปฏิบัติร่วมกันโดยทั่วไปและไม่ใช่คุณสมบัติที่สำคัญของภาษา"
KeithS

@ KeithS วิกิพีเดียยังไม่สมบูรณ์แบบ ความจริงที่ว่าบทความมีอยู่สำหรับคำที่ไม่ถูกต้องไม่ทำให้คำนี้ถูกต้องอีกต่อไป ใช่ภาษาได้รับการออกแบบโดยคำนึงถึงรูปแบบการดำเนินการบางอย่างเสมอ แต่มันก็ยังต่อต้านการสร้างแบรนด์ที่พวกเขา "รวบรวม" หรือ "ตีความ" เพียงอย่างเดียวตามความตั้งใจของนักออกแบบ และสำหรับการตีความมันเป็นการยากที่จะหา "ล่าม" ที่เหมาะสมไม่ว่าด้วยวิธีใด Tcl น่าจะเป็นคนสุดท้ายของมัน "ล่าม" อื่น ๆ ทั้งหมดเรียกว่า compiler ในความเป็นจริง
SK-logic

2

ภาษาที่มีการจัดการในแง่ง่ายมันเป็นภาษาระดับสูงที่ขึ้นอยู่กับบริการที่จัดทำโดยสภาพแวดล้อมแบบรันไทม์เพื่อดำเนินการเช่นบริการเก็บรวบรวมขยะนั่นคือสาเหตุที่เรียกว่าจัดการโดยทั่วไป แต่ไม่ใช่บริการเดียวที่ใช้ และบริการเหล่านี้บางตัวsecurity services, exception handling, standard typesก็ใช้Common Language Run-time CLRเพื่อดำเนินการเช่นใน. Net languages ​​หรือสภาพแวดล้อมเสมือนเช่น Java ซึ่งใช้ `Java Virtual Machine JVM

Unmanaged Languageเป็นภาษาระดับต่ำที่ปฏิบัติการโดยตรงจากระบบปฏิบัติการโดยไม่จำเป็นต้องใช้บริการรันไทม์เสมือนจริงหรือภาษากลางเช่นภาษาเช่นC, C++รหัสที่ไม่มีการจัดการที่สร้างโดยภาษาดังกล่าวใช้ไลบรารีรูทีนที่เชื่อมโยงกับระบบปฏิบัติการแบบไดนามิก รหัสในการเรียกใช้ DLLs (Dynamic Link Libraries) รหัสที่ไม่มีการจัดการเข้าถึงหน่วยความจำโดยตรงนั่นคือสาเหตุที่มันเร็วกว่ารหัสที่ได้รับการจัดการ แต่ถ้าคุณกำลังสร้างไดรเวอร์ฮาร์ดแวร์หรือวิดีโอเกมที่ซับซ้อนคุณไม่ต้องการใช้ภาษาที่ไม่มีการจัดการ การทำงานกับอันตรายโดยเฉพาะอย่างยิ่งกับผู้พัฒนาที่ไม่มีประสบการณ์เช่นสถานะบทบาทอาจเป็นอันตรายได้with great power comes great responsibilityและนั่นคือสาเหตุที่ภาษาที่มีการจัดการมีอยู่เพื่อช่วยให้นักพัฒนาสร้างโค้ดที่ขยายได้โดยไม่ต้องดำลงไปด้านล่างของระบบ แต่คุณยังสามารถสร้างรหัสผสมได้หากคุณต้องการบทความเหล่านี้อธิบายทั้งหมด:

ภาพรวมของการทำงานร่วมกันของรหัสที่จัดการ / ไม่มีการจัดการ

ตัวอย่าง: การผสมรหัส C ++, C ++ / CLI ที่ไม่มีการจัดการและการผสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.