Runtime στην ανάπτυξη εφαρμογών για κινητά: τι είναι, σύστημα runtime και πώς λειτουργεί

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-17 Χρόνος ανάγνωσης: 9 λεπ

Runtime είναι ένα επίπεδο λογισμικού που διαχειρίζεται την εκτέλεση του κώδικα μιας εφαρμογής για κινητά: κατανέμει μνήμη, διαχειρίζεται εξαιρέσεις, εκκινεί το garbage collection και διανέμει τις κλήσεις μεθόδων. Χωρίς runtime καμία εφαρμογή δεν μπορεί να εκτελεστεί — είναι το ενδιάμεσο επίπεδο μεταξύ του μεταγλωττισμένου κώδικα και του λειτουργικού συστήματος. Σύμφωνα με Android Developer Documentation, 2025, το περιβάλλον εκτέλεσης είναι το βασικό στοιχείο της πλατφόρμας που καθορίζει την απόδοση και τη συμβατότητα.

Τα βασικά

  • Runtime είναι το περιβάλλον λογισμικού που εκτελεί το bytecode ή τον κώδικα μηχανής μιας εφαρμογής για κινητά.
  • ART (Android Runtime) χρησιμοποιεί μεταγλώττιση AOT και αντικατέστησε το Dalvik από το Android 5.0.
  • Objective-C Runtime παρέχει δυναμική διανομή μεθόδων και message passing στο iOS.
  • Μεταγλώττιση JIT μεταγλωττίζει το bytecode σε κώδικα μηχανής απευθείας κατά την εκτέλεση της εφαρμογής.
  • ARM64 Runtime είναι το επίπεδο υλικού στο οποίο εκτελείται ο βελτιστοποιημένος κώδικας για επεξεργαστές ARM 64-bit.

Τι είναι το Runtime στην ανάπτυξη εφαρμογών για κινητά;

Runtime (περιβάλλον εκτέλεσης) είναι η υποδομή που εξασφαλίζει την εκτέλεση ενός προγράμματος μετά την εκκίνησή του. Στο πλαίσιο της ανάπτυξης εφαρμογών για κινητά, το runtime περιλαμβάνει τον φορτωτή κλάσεων, τον κατανεμητή μνήμης, το garbage collector, τον διανομέα μεθόδων και τον χειριστή εξαιρέσεων. Χωρίς αυτό το ενδιάμεσο επίπεδο, το λειτουργικό σύστημα δεν μπορεί να εκτελέσει το bytecode 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: από ποια στοιχεία αποτελείται

Το σύστημα runtime περιλαμβάνει πέντε βασικά στοιχεία: φορτωτή κλάσεων, διαχειριστή μνήμης, διερμηνέα ή μεταγλωττιστή, διανομέα μεθόδων και σύστημα ασφαλείας. Κάθε στοιχείο επιτελεί μια αυστηρά καθορισμένη λειτουργία στη διαδικασία εκτέλεσης κώδικα.

Φορτωτής κλάσεων και επαλήθευση

Όταν ο χρήστης εκκινεί την εφαρμογή, ο ClassLoader φορτώνει τα αρχεία DEX (Android) ή τα δυαδικά Mach-O (iOS) στη μνήμη εργασίας. Στο Android, αυτό το στάδιο περιλαμβάνει την επαλήθευση του bytecode: το runtime ελέγχει ότι ο κώδικας δεν περιέχει επικίνδυνες εντολές, δεν υπερβαίνει τα όρια των πινάκων και τηρεί τους τύπους. Η επαλήθευση είναι ένα κρίσιμο βήμα ασφαλείας που αποτρέπει την εκτέλεση κακόβουλου κώδικα.

Διαχειριστής μνήμης και Garbage Collector

Ο 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 για να επιταχύνει τις επαναλαμβανόμενες κλήσεις.

Πώς λειτουργεί το ART στο Android

Android Runtime (ART) είναι μια εικονική μηχανή που εκτελεί το bytecode 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, που εξισορροπεί την ταχύτητα μεταγλώττισης και την απόδοση κώδικα.

kotlin
class RuntimeExample {
    fun measureExecutionTime() {
        val start = System.nanoTime()
        // Κλήση μεθόδου που μεταγλωττίζεται από το ART
        processData()
        val end = System.nanoTime()
        println("Χρόνος εκτέλεσης: ${end - start} ns")
    }
}

Στο παραπάνω παράδειγμα, το System.nanoTime() είναι μια εγγενής μέθοδος της οποίας η κλήση διανέμεται μέσω του ART runtime στον πυρήνα Linux. Το ART μετατρέπει το bytecode Kotlin σε εντολές ARM64, τις οποίες εκτελεί ο επεξεργαστής της συσκευής. Αυτή η διαδικασία γίνεται απαρατήρητα για τον προγραμματιστή, αλλά η βελτιστοποίησή της είναι βασικό καθήκον της ομάδας Android Platform.

Profile-Guided Optimization (PGO)

Η βελτιστοποίηση που βασίζεται σε προφίλ είναι ένας μηχανισμός ART που συλλέγει προφίλ χρήσης μεθόδων. Το αρχείο profiles/.primary.prof περιέχει τη λίστα των hot μεθόδων που μεταγλωττίζονται AOT. Σύμφωνα με το Android Performance Team, το PGO επιταχύνει την εκκίνηση της εφαρμογής κατά 15–30% μετά από λίγες ημέρες χρήσης, όταν το προφίλ έχει συλλεχθεί.

Ο προγραμματιστής μπορεί να ενεργοποιήσει τα baseline profiles στο έργο του Gradle. Πρόκειται για χειροκίνητους σχολιασμούς που υποδεικνύουν στο ART ποιες μεθόδους να μεταγλωττίσει AOT αμέσως μετά την εγκατάσταση. Τα baseline profiles μειώνουν την πρώτη εκκίνηση κατά 40% χωρίς να περιμένουν την προφιλοποίηση παρασκηνίου.

Πώς λειτουργεί το Objective-C Runtime στο iOS

Objective-C Runtime είναι μια δυναμική βιβλιοθήκη που εξασφαλίζει την εκτέλεση κώδικα Objective-C σε iOS και macOS. Ο πυρήνας της είναι η συνάρτηση objc_msgSend, η οποία υλοποιεί το message passing: αντί για άμεση κλήση μεθόδου, το αντικείμενο στέλνει ένα μήνυμα με selector, και το runtime καθορίζει ποια υλοποίηση πρέπει να εκτελεστεί.

Κάθε αντικείμενο Objective-C περιέχει έναν δείκτη isa στην κλάση, και η κλάση έχει έναν dispatch table (πίνακα διανομής) που αντιστοιχίζει τους selectors (SEL) σε υλοποιήσεις (IMP). Όταν καλείται μια μέθοδος, το objc_msgSend διασχίζει την αλυσίδα: κλάση → υπερκλάση → NSObject, μέχρι να βρει IMP. Αν η υλοποίηση δεν βρεθεί, το runtime καλεί τον μηχανισμό forwarding, ο οποίος μπορεί να αναχαιτίσει το μήνυμα ή να δημιουργήσει εξαίρεση.

Το Objective-C Runtime υποστηρίζει επίσης το method swizzling — την αντικατάσταση του IMP ενός υπάρχοντος selector κατά την εκτέλεση. Είναι ένας ισχυρός μηχανισμός που χρησιμοποιείται σε βιβλιοθήκες AOP και εργαλεία παρακολούθησης, αλλά απαιτεί προσοχή λόγω της επίδρασής του σε ολόκληρη την εφαρμογή.

objective-c
@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 και tagged pointers

isa pointer είναι ένας δείκτης στην κλάση του αντικειμένου, που αποθηκεύεται στα πρώτα 8 bytes κάθε αντικειμένου. Από το iOS 12, η Apple εισήγαγε το isa-swizzling για βελτιστοποίηση: τα κατώτερα bits του isa κωδικοποιούν πρόσθετες πληροφορίες για την κατάσταση του αντικειμένου. Οι tagged pointers είναι μια άλλη βελτιστοποίηση, όπου τιμές έως 60 bit (NSNumber, NSDate) αποθηκεύονται απευθείας στον δείκτη, χωρίς κατανομή αντικειμένου στο heap. Αυτό μειώνει το φορτίο του διαχειριστή μνήμης κατά 30%.

Μεταγλώττιση JIT και AOT: σύγκριση προσεγγίσεων

JIT (Just-In-Time) και AOT (Ahead-Of-Time) είναι δύο προσεγγίσεις για τη μεταγλώττιση bytecode σε κώδικα μηχανής. Το JIT μεταγλωττίζει τον κώδικα κατά την εκτέλεση της εφαρμογής, αναλύοντας τα καυτά σημεία και βελτιστοποιώντας τα εν κινήσει. Το AOT μεταγλωττίζει ολόκληρο τον κώδικα εκ των προτέρων — κατά την εγκατάσταση της εφαρμογής ή από την πλευρά του προγραμματιστή.

ΧαρακτηριστικόJITAOT
Χρόνος μεταγλώττισηςΚατά την εκτέλεσηΚατά την εγκατάσταση / δημιουργία
Μέγεθος APK/IPAΜικρότερο (μόνο bytecode)Μεγαλύτερο (κώδικας μηχανής)
Ταχύτητα εκκίνησηςΧαμηλότερη (απαιτείται μεταγλώττιση)Υψηλότερη (κώδικας έτοιμος για εκτέλεση)
Βελτιστοποίηση για τη συσκευήΝαι (προσαρμοστική)Περιορισμένη (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 Runtime είναι το επίπεδο στο οποίο ο κώδικας μηχανής αλληλεπιδρά με τον επεξεργαστή της συσκευής. Οι περισσότερες σύγχρονες συσκευές για κινητά λειτουργούν σε επεξεργαστές ARM64 (aarch64). Το runtime μεταφράζει το bytecode ή τις εγγενείς κλήσεις σε εντολές ARM64, τις οποίες εκτελεί η CPU.

Οι βασικοί καταχωρητές ARM64 που χρησιμοποιεί το runtime: x0–x7 (παράμετροι συναρτήσεων), x8 (έμμεσο αποτέλεσμα), x30 (διεύθυνση επιστροφής), sp (stack pointer), fp (frame pointer). Το ART παράγει κώδικα που τηρεί το ARM64 Procedure Call Standard: όλες οι κλήσεις μεθόδων περνούν από το πρωτόκολλο που ορίζει η αρχιτεκτονική του επεξεργαστή.

Η κατανόηση του ARM64 ABI είναι σημαντική στη βελτιστοποίηση της απόδοσης: η ενσωματωμένη προσωρινή μνήμη, η πρόβλεψη διακλαδώσεων και η στοίχιση του κώδικα στη μνήμη επηρεάζουν άμεσα την ταχύτητα λειτουργίας του runtime. Τα εργαλεία προφιλοποίησης (Android Studio Profiler, Instruments) δείχνουν ποια τμήματα κώδικα περνούν τον περισσότερο χρόνο στο runtime — η βελτιστοποίηση ακριβώς αυτών δίνει τη μεγαλύτερη βελτίωση.

cpp
// Παράδειγμα 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 στην απόδοση

Runtime overhead είναι το αναπόφευκτο κόστος της δυναμικής διανομής. Κάθε κλήση μεθόδου μέσω του runtime απαιτεί: αναζήτηση της υλοποίησης στον dispatch table, έλεγχο τύπων, κλήση του IMP και επιστροφή του αποτελέσματος. Οι μετρήσεις δείχνουν ότι το runtime προσθέτει 10–50 ns ανά κλήση στο Objective-C και 5–20 ns στο ART.

Για τη μείωση της επιβάρυνσης, οι προγραμματιστές χρησιμοποιούν monomorphic inlining (ART) και method caching (Objective-C). Το Kotlin/Native και η Swift μεταγλωττίζονται απευθείας σε ARM64, εξαλείφοντας εντελώς το επίπεδο runtime, αλλά χάνοντας τις δυναμικές δυνατότητες — το reflection, το swizzling, τη δυναμική φόρτωση κλάσεων.

Συχνές ερωτήσεις

Σε τι διαφέρει το Runtime από το SDK;

SDK (Software Development Kit) είναι ένα σύνολο εργαλείων για την ανάπτυξη της εφαρμογής (μεταγλωττιστής, βιβλιοθήκες, βοηθητικά προγράμματα). Το Runtime είναι το περιβάλλον στο οποίο η ήδη αναπτυγμένη εφαρμογή εκτελείται στη συσκευή. Το SDK χρειάζεται ο προγραμματιστής, το runtime — ο χρήστης.

Μπορεί να αντικατασταθεί το Runtime σε μια εφαρμογή για κινητά;

Όχι — το runtime είναι μέρος του λειτουργικού συστήματος και δεν μπορεί να αντικατασταθεί από τον χρήστη. Το ART είναι ενσωματωμένο στο Android Framework, το Objective-C Runtime — στο iOS. Ο προγραμματιστής μπορεί να επιλέξει γλώσσα (Kotlin/Native χωρίς runtime) ή να χρησιμοποιήσει εικονικές μηχανές όπως η Dart VM στο Flutter.

Επηρεάζει το Runtime την κατανάλωση μπαταρίας;

Ναι, το runtime επηρεάζει την κατανάλωση ενέργειας. Το Garbage collection στο ART και το Swift runtime χρησιμοποιούν CPU, γεγονός που αυξάνει την κατανάλωση μπαταρίας. Βελτιστοποιήσεις όπως το concurrent GC και οι tagged pointers στο iOS μειώνουν την επίδραση του runtime στην μπαταρία κατά 20–30%.

Τι είναι το runtime error και πώς να το πιάσουμε;

Runtime error είναι ένα σφάλμα που εμφανίζεται κατά την εκτέλεση: null pointer exception, index out of bounds, διαίρεση με το μηδέν. Σε αντίθεση με τα σφάλματα μεταγλώττισης, αυτά δεν ανιχνεύονται κατά τη δημιουργία. Πιάνονται μέσω μπλοκ try-catch ή αναφορών σφαλμάτων (Firebase Crashlytics, Sentry).

Πώς διαφέρει το Swift runtime από το Objective-C Runtime;

Swift runtime είναι ελαφρύτερο από το Objective-C: δεν υποστηρίζει dynamic dispatch από προεπιλογή, χρησιμοποιεί value types (struct) χωρίς κατανομή στο heap και δεν έχει message forwarding. Οι μέθοδοι Swift καλούνται απευθείας μέσω vtable, αν δεν επισημαίνονται με @objc dynamic. Αυτό δίνει αύξηση ταχύτητας έως 5 φορές στα benchmark.

Συμπεράσματα

  • Runtime είναι το περιβάλλον εκτέλεσης που διαχειρίζεται τη μνήμη, τις μεθόδους και την ασφάλεια του κώδικα.
  • ART (Android) χρησιμοποιεί υβρίδιο JIT/AOT με profile-guided optimization για βέλτιστη απόδοση.
  • Objective-C Runtime βασίζεται στο message passing μέσω objc_msgSend και dispatch table.
  • JIT μεταγλωττίζει τον κώδικα εν κινήσει και προσαρμόζεται στη συσκευή, το AOT μεταγλωττίζει εκ των προτέρων για γρήγορη εκκίνηση.
  • ARM64 Runtime είναι το επίπεδο υλικού που εκτελεί κώδικα μηχανής σε σύγχρονους επεξεργαστές.
  • Runtime overhead είναι 5–50 ns ανά κλήση μεθόδου και ελαχιστοποιείται με inlining και προσωρινή μνήμη.
  • Η κατανόηση του runtime είναι απαραίτητη για τη βελτιστοποίηση της απόδοσης, τον εντοπισμό σφαλμάτων και την επιλογή της αρχιτεκτονικής της εφαρμογής.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης