Runtime је софтверски слој који управља извршавањем кода мобилне апликације: додељује меморију, обрађује изузетке, покреће garbage collection и диспечује позиве метода. Без runtime-а ниједна апликација не може да се извршава — то је прослој између компилираног кода и оперативног система. Према Android Developer Documentation, 2025, окружење за извршавање је кључни елемент платформе који одређује перформансе и компатибилност.
Најважније
Runtime (окружење за извршавање) је инфраструктура која обезбеђује извршавање програма након његовог покретања. У контексту мобилног развоја, runtime укључује учитавач класа, алокатор меморије, garbage collector, диспечер метода и обрађивач изузетака. Без овог прослоја оперативни систем не може да изврши Dalvik бајт-код или Objective-C поруке.
Мобилне платформе користе различите имплементације runtime-а. Android користи ART (Android Runtime) са хибридном AOT/JIT компилацијом. iOS користи Objective-C Runtime — динамички систем заснован на message passing-у и SEL идентификаторима. Оба приступа решавају исти задатак: извршити код програмера на конкретном уређају са максималним перформансама.
Према Google I/O 2024, Android Runtime обради преко 10 милијарди метода дневно на уређајима широм света. Перформансе runtime-а директно утичу на брзину покретања апликације, глаткоћу анимација и потрошњу батерије. Сваки позив метода, свака алокација меморије и сваки циклус garbage collection-а пролазе кроз слој runtime-а.
Runtime систем укључује пет кључних компоненти: учитавач класа, менаџер меморије, интерпретатор или компилатор, диспечер метода и систем безбедности. Свака компонента обавља строго одређену функцију у процесу извршавања кода.
Када корисник покрене апликацију, ClassLoader учитава DEX фајлове (Android) или Mach-O бинарне фајлове (iOS) у радну меморију. На Android-у ова фаза укључује верификацију бајт-кода: runtime проверава да код не садржи небезбедне инструкције, не излази из граница низова и поштује типове. Верификација је критичан корак безбедности који спречава извршавање злонамерног кода.
Memory Manager додељује и ослобађа меморију за објекте. На Android-у, ART користи конкуретни garbage collector са генерацијским сакупљањем: млади објекти се проверавају чешће, а стари — ређе. Objective-C Runtime користи Automatic Reference Counting (ARC), где компилатор аутоматски убацује позиве retain/release.
Method dispatcher одређује која имплементација метода ће бити позвана. У статичким језицима (Kotlin, Swift) распоређивање се врши кроз vtable — табелу виртуелних метода. У динамичким (Objective-C) порука пролази кроз objc_msgSend, који тражи имплементацију у класи и њеним надкласама. Резултат се кешира у method cache ради убрзавања поновљених позива.
Android Runtime (ART) је виртуелна машина која извршава DEX бајт-код Android апликација. ART је заменио Dalvik у Android 5.0 Lollipop, предложивши AOT компилацију: апликација се компилира у машински код једном током инсталације. То је елиминисало додатне трошкове JIT компилације при сваком покретању.
Почевши од Android 7.0 Nougat, ART користи хибридни приступ. При инсталацији се извршава JIT компилација само често коришћених метода (hot methods), док се остали код интерпретира. Позадински процес (profile-guided optimization) анализира који се методи најчешће позивају и компилира их AOT током периода неактивности уређаја. То скраћује време инсталације и истовремено обезбеђује високе перформансе.
ART такође укључује AOT compiler (dex2oat), који претвара DEX фајлове у ELF бинарне фајлове са ARM64 машинским кодом. Компилација се извршава са три нивоа оптимизације: quicken (брза), optimize (средња) и everything (потпуна). Подразумевано, Android примењује optimize, што балансира између брзине компилације и перформанси кода.
class RuntimeExample {
fun measureExecutionTime() {
val start = System.nanoTime()
// Позив метода кога компилира ART
processData()
val end = System.nanoTime()
println("Време извршавања: ${end - start} нс")
}
}У примеру изнад, System.nanoTime() је нативни метод чији се позив диспечује кроз ART runtime у Linux кернел. ART претвара Kotlin бајт-код у ARM64 инструкције, које извршава процесор уређаја. Овај процес се одвија неприметно за програмера, али је његова оптимизација кључни задатак Android Platform тима.
Оптимизација вођена профилом је механизам ART-а који сакупља профиле коришћења метода. Фајл profiles/
Програмер може да укључи baseline profiles у свом Gradle пројекту. То су ручне анотације које ART-у указују које методе да компилира AOT одмах након инсталације. Baseline profiles скраћују прво покретање за 40% без чекања на позадинско профилисање.
Objective-C Runtime је динамичка библиотека која обезбеђује извршавање Objective-C кода на iOS и macOS платформама. Њено језгро је функција objc_msgSend, која имплементира message passing: уместо директног позива метода, објекат шаље поруку са селектором, а runtime одређује која имплементација треба да се изврши.
Сваки Objective-C објекат садржи isa показивач на класу, а класа има dispatch table (табелу распоређивања) која повезује селекторе (SEL) са имплементацијама (IMP). Када се метод позове, objc_msgSend пролази кроз ланац: класа → надкласа → NSObject, док не пронађе IMP. Ако имплементација није пронађена, runtime покреће forwarding mechanism, који може да пресретне поруку или да генерише изузетак.
Objective-C Runtime такође подржава method swizzling — замену IMP-а за постојећи селектор током извршавања. То је моћан механизам који се користи у AOP библиотекама и алатима за праћење, али захтева опрез због утицаја на целу апликацију.
@interface RuntimeDemo : NSObject
- (void)printClassInfo;
@end
@implementation RuntimeDemo
- (void)printClassInfo {
// objc_getClass — runtime функција
Class cls = objc_getClass("RuntimeDemo");
unsigned int count;
Method *methods = class_copyMethodList(cls, &count);
NSLog("Број метода: %d", count);
}
@endКод демонстрира директан приступ Objective-C Runtime API-ју: objc_getClass добија објекат класе по имену, а class_copyMethodList извлачи листу свих метода. То је reflection на делу — приступ метаподацима класе током извршавања. Овај приступ се користи у XCTest-у за динамичку регистрацију тестова.
isa pointer је показивач на класу објекта, смештен у првих 8 бајтова сваког објекта. Од iOS 12, Apple је увео isa-swizzling ради оптимизације: млађи битови isa-е кодирају додатне информације о стању објекта. Tagged pointers су још једна оптимизација, где се вредности до 60 бита (NSNumber, NSDate) чувају директно у показивачу, без алокације објекта у хипу. То смањује оптерећење менаџера меморије за 30%.
JIT (Just-In-Time) и AOT (Ahead-Of-Time) су два приступа компилацији бајт-кода у машински. JIT компилира код током извршавања апликације, анализирајући вруће секције и оптимизујући их у ходу. AOT компилира сав код унапред — при инсталацији апликације или на страни програмера.
| Карактеристика | JIT | AOT |
|---|---|---|
| Време компилације | Током извршавања | При инсталацији / билдовању |
| Величина APK/IPA | Мања (само бајт-код) | Већа (машински код) |
| Брзина покретања | Нижа (потребна компилација) | Виша (код је спреман за извршавање) |
| Оптимизација за уређај | Да (адаптивна) | Ограничена (generic) |
| Потрошња RAM-а | Виша (компилатор у меморији) | Нижа |
Хибридни приступ ART-а (Android 7+) сматра се оптималним: апликација користи интерпретатор за ретко позиване методе, JIT за hot методе и AOT за методе из profile-guided optimization-а. iOS, насупрот томе, користи строги AOT кроз LLVM: Swift и Objective-C се компилирају у машински код у фази билдовања у Xcode-у.
Према Apple Developer Documentation, 2024, Swift runtime додаје око 15 MB величини апликације. Flutter користи своју Dart VM, где JIT компилација ради у debug режиму за hot reload, а AOT — у release режиму за максималне перформансе. React Native користи Hermes — JavaScript мотор са AOT компилацијом, који скраћује време покретања за 50%.
ARM64 Runtime је ниво на коме машински код комуницира са процесором уређаја. Већина савремених мобилних уређаја ради на ARM64 (aarch64) процесорима. Runtime преводи бајт-код или нативне позиве у ARM64 инструкције, које извршава CPU.
Кључни ARM64 регистри које користи runtime: x0–x7 (параметри функција), x8 (индиректни резултат), x30 (адреса повратка), sp (stack pointer), fp (frame pointer). ART генерише код који поштује ARM64 Procedure Call Standard: сви позиви метода пролазе кроз протокол дефинисан архитектуром процесора.
Разумевање ARM64 ABI важно је при оптимизацији перформанси: inline кеширање, предвиђање гранања и поравнање кода у меморији директно утичу на брзину рада runtime-а. Алати за профилисање (Android Studio Profiler, Instruments) показују који делови кода проводе највише времена у runtime-у — управо њихова оптимизација даје највећи напредак.
// Пример ARM64 assembly-а кога генерише ART
// Позив метода са два параметра
mov x0, x23 // self (this)
mov x1, x24 // param1
mov x2, x25 // param2
bl methodEntryPoint // позив кроз runtime
str x0, [sp, #8] // чување резултатаУ овом примеру ARM64 инструкције mov преносе аргументе у регистре x0–x2, bl позива улазну тачку метода, а str чува повратну вредност. Runtime генерише такве инструкције за сваки позив метода, оптимизујући секвенцу кроз devirtualization и inlining.
Runtime overhead је неизбежна цена динамичког распоређивања. Сваки позив метода кроз runtime захтева: тражење имплементације у dispatch table, проверу типова, позив IMP-а и враћање резултата. Мерења показују да runtime додаје 10–50 нс по позиву у Objective-C-у и 5–20 нс у ART-у.
За смањење overhead-а, програмери користе monomorphic inlining (ART) и method caching (Objective-C). Kotlin/Native и Swift се компилирају директно у ARM64, потпуно елиминишући runtime прослој, али губећи динамичке могућности — рефлексију, swizzling, динамичко учитавање класа.
Често постављана питања
SDK (Software Development Kit) је скуп алата за развој апликације (компилатор, библиотеке, алати). Runtime је окружење у коме се већ развијена апликација извршава на уређају. SDK је потребан програмеру, а runtime — кориснику.
Не — runtime је део оперативног система и не може га корисник заменити. ART је уграђен у Android Framework, а Objective-C Runtime — у iOS. Програмер може да бира језик (Kotlin/Native без runtime-а) или да користи виртуелне машине попут Dart VM у Flutter-у.
Да, runtime утиче на потрошњу енергије. Garbage collection у ART-у и Swift runtime користе CPU, што повећава потрошњу батерије. Оптимизације попут concurrent GC-а и tagged pointers-а на iOS-у смањују утицај runtime-а на батерију за 20–30%.
Runtime error је грешка која настаје током извршавања: null pointer exception, index out of bounds, дељење нулом. За разлику од compile-time грешака, оне се не откривају при билдовању. Хватају се кроз try-catch блокове или crash reporting (Firebase Crashlytics, Sentry).
Swift runtime је лакши од Objective-C-а: не подржава dynamic dispatch подразумевано, користи value types (struct) без алокације у хипу и нема message forwarding. Swift методи се позивају директно кроз vtable, ако нису означени са @objc dynamic. То даје повећање брзине до 5x у бенчмарковима.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође