Виртуални машини
I. Опростени дефиницииII. Вариации във виртуалните машини
III. Програмни езици
IV. Особености
I. Опростени дефиниции
- език - правила, определящи синтаксиса на текста, който ще се компилира до изпълним код. Самият текст се нарича изходен код. Може да е разпределен в един или повече текстови файлове.
- компилатор - програма, която преобразува изходния код за даден език до изпълним код.
- изпълним код - последователност от инструкции за реален (физически) процесор или за процесор на виртуална машина. Може да е в един файл (програма) или да е разпределен в няколко файла (програми, статични и/или динамични библиотеки). Файловете с изпълним код за .Net се наричат асемблита. В Java за всеки клас се създава отделен файл с изпълним код - class файл. Тези class файлове се архивират в jar (Java ARchive) файлове. Асемблитата и jar-овете съдържат т.нар. метаданни в допълнение към компилирания изпълним код.
-
виртуален процесор - програма, която интерпретира свой собствен изпълним код (виртуален код).
Самият виртуален процесор се изпълнява на физически процесор и работата му е да превежда
виртуалния си код до изпълним код за физическия процесор.
В действителност разликата между кода за виртуалните и реалните процесори е голяма и не е възможно директно линейно съпоставяне на една виртуална инструкция към една реална. Често една инструкция във виртуалния процесор се свежда до много за реалния. Това превръща виртуалните процесори в един вид компилатори, които компилират виртуалния си код до код за даден реален процесор. -
виртуална машина - система, състояща се от:
- виртуален процесор
- Garbage collector - "събирач на боклук", т.е. освобождава паметта, заета от обекти, които не се използват вече.
- системи за защита, идентификация и оторизация при изпълнението на виртуалния код
- система за динамично управление на кода (reflection)
- базови библиотеки - с тяхна помощ програмистите могат да впрегнат в работа гореизброените неща. Често библиотеките се разглеждат отделно от предишните точки (наречени runtime). В този случай библиотеките се възприемат като програмен интерфейс за използване на runtime и се наричат framework. От такава гледна точка, виртуалните машини са съставени от две части - runtime и framework.
- Компилация по време на изпълнение (JIT) - позволява се по-голяма защита от неоторизирано изпълнение на потенциално опасен код. Освен това динамичното генериране и обработка на managed код (reflection) е възможно само в този вариант.
- Предварителна компилация до native код - използва се заради по-бързото изпълнение.
II. Вариации във виртуалните машини
Java е виртуална машина, която се поддържа за различни видове хардуери и операционни системи. Вариантите, в които се издава обхващат цялата виртуалната машина (не само основните библиотеки):- Стандарт - за Desktop приложения
- За предприятия (Enterprise) - силно разширен вариант за Web и Desktop приложения
- Микро - за мобилни устройства или микроконтролери
За разлика от Java, Microsoft поддържат .Net само за техните операционни системи (различните Windows-и). Изданията на .Net са много по-ограничени от тези на Java, защото обхващат само основните библиотеки (т.е. framework-а):
- Основно издание - за Desktop приложения
- Компактно издание - за мобилни устройства и всякакви компютри, работещи с Windows CE
III. Програмни езици
В началото Java обединяваше езика и виртуалната машина и съответно имаше компилатори само за езика Java (javac) и за мнемоничния код на виртуалния процесор (jasmin). След появата на .Net и неговата многоезичност, за Java също се създадоха компилатори за различни езици. В днешно време и двете виртуални машини имат "основни езици" - езикът Java за Java VM и езикът C# за .Net CLR. Тъй като основно за .Net се пише на два езика - VB (Visual Basic) и C#, то преобразуването на код между двата езика се налага често (има много код само на единия или само на другия език). За по-лесно преобразуване има сравнителни статии, а за по-мързеливите има и автоматични конвертори.Декомпилацията е характерна особеност и за двете виртуални машини. За Java се използва декомпилатор за езика Java (jad) и до мнемоничен код (jasper). За .Net се използва най-често Reflector (може да декомпилира до няколко от основните езици: MSIL, C#, Visual Basic, C++) и ILSpy (може да декомпилира само до MSIL и C#, но е безплатен).
IV. Особености
Java е по-стара и има повече създаден код за нея (особено за Java Enterprise). Тя е мултиплатформена и се изпълнява на огромно разнообразие от хардуери (компютри, мобилни устройства, микроконтролери) и операционни системи. Като по-стара виртуална машина, Java е и по-модулна. Например Garbage collector-ът позволява да се изпълнява с различни алгоритми в зависимост от изискванията за запълване на паметта и за натоварване на процесора. Като по-нов, в .Net никога не е имало проблеми, които Java имаше доскоро или от които все още не се е отървала. Създаването на потребителски интерфейс в .Net е несравнимо по-лесно и самият интерфейс е по-лек и функционален. Все пак, макар и по-нов не може да се отрече, че .Net има доста трески за дялане. Паралелната обработка и синхронизациятя в Java е по-проста и по-удобна като остава напълно съпоставима от функционална гледна точка с .Net. Дизайн-тайм на .Net, който е заимстван от продукта Delphi на Borland, има проблеми, които Delphi не е имал.Взаимодействието с native код е различно - под Windows .Net има известно предимство, но от своя страна JNI (Java Native Interface) има и своите силни страни. В .Net има нещото наречено mixed-mode (managed-native) асемблита - съдържат едновременно managed и unmanaged код. Те могат да се пишат само на езика C++ (този език се поддържа от компилатора както за native, така и за managed код).
За мултимедийни приложения Java предоставя библиотеката JMF (Java Media Framework), но поради ограниченията й често се използва и QuickTime for Java (обвивка на QuickTime API за Java). За .Net има managed обвивка на DirectX в самите SDK (за DirectX версия 9 и по-късни; преди нея се работи с COM Interoperation). За Media Foundation няма обвивка, но може да се направи.