03 Η ιδεατή μηχανή της Java Τεχνολογία Λογισμικού Τμήμα Πληροφορικής & Τηλεπικοινωνιών, ΕΚΠΑ Εαρινό εξάμηνο 2016 17 Δρ. Κώστας Σαΐδης saiko@di.uoa.gr
Περιεχόμενα Η πλατφόρμα της Java γενικά Εισαγωγή στο Java Virtual Machine JVM Γλώσσες που υποστηρίζονται από το JVM 2
Η πλατφόρμα της Java Java Runtime Environment JRE Java virtual machine Java class library Java Development Kit JDK JRE + Eργαλεία ανάπτυξης κώδικα σε γλώσσα Java javac java compiler javadoc παραγωγή HTML τεκμηρίωσης από τον πηγαίο κώδικα jdb debugger κ.ά. 3
Java Class Library Τα βασικά APIs Αξίζει να σταθούμε λίγο I/O & Networking Files, Sockets, κ.ά Threads Collections & Streams v8 Security & Encryption SQL Databases XML GUI swing 4
Ανάπτυξη της Java Java Community Process JCP Java Specification Requests JSRs Reference implementations of APIs Open JDK GNU GPL v2 Reference implementation of Java JVM + Tools + Class Library 5
Σύντομη εισαγωγή στο JVM 6
Βασικά χαρακτηριστικά Διαλειτουργικότητα Portability Write once, run everywhere Αυτόματη διαχείριση μνήμης Garbage collection Υποστήριξη για πολλαπλά threads Just In Time Μεταγλώττιση Γρήγορο, στιβαρό, αξιόπιστο και διεθνώς διαδεδομένο περιβάλλον εκτέλεσης σε servers, desktops, κινητά, άλλες συσκευές 7
Η Δομή του JVM By Michelle Ridomi Own work, CC BY SA 4.0, https://commons.wikimedia.org/w/index.php?curid=35963523 8
Class Loader Μηχανισμός που επιτρέπει την παραμετροποιήσιμη προγραμματιστικά φόρτωση των κλάσεων στο JVM.class files, bytecode Οι class loaders είναι "κανονικά" Java αντικείμενα τύπου java.lang.classloader Μια εφαρμογή Java μπορεί να έχει πολλαπλούς class loaders 9
Ορισμός κλάσεων java.lang.class Κατά την εκτέλεση του προγράμματος, οι κλάσεις αναπαρίστανται από "κανονικά" Java αντικείμενα reflection Προσοχή Για την ίδια κλάση, όταν αυτή φορτώνεται από διαφορετικούς class loaders, παράγονται διαφορετικά Class αντικείμενα. 10
Βήματα 1. Χρήση του class loader για φόρτωση της κλάσης από το δίσκο, το δίκτυο ή από κάπου αλλού π.χ. δυναμική επιτόπου παραγωγή της, on the fly 2. Σύνδεση της κλάσης linking Επιβεβαίωση bytecode Εντοπισμός και αρχικοποίηση εξαρτήσεων 3. Αρχικοποίηση της κλάσης static πεδία, blocks και μέθοδοι 11
Αρχικοποίηση κλάσεων Οκνηρή / lazy ακριβώς πριν την πρώτη χρήση τους. Που είναι πότε; Πριν στιγμιοτυπιθεί ένα αντικείμενο της κλάσης. Πριν κληθεί μια static μέθοδος της κλάσης. Πριν προσπελαστεί ένα static πεδίο της κλάσης είτε για ανάγνωση, είτε για εγγραφή της τιμής του Η αρχικοποίηση μιας κλάσης προϋποθέτει την αρχικοποίηση της υπερ κλάσης της super class. Η αρχικοποίηση μιας κλάσης γίνεται μόνο μία φορά ανά class loader. 12
Διάφανη χρήση των class loaders από το JVM To JVM διαθέτει έναν Bootstap class loader για τη φόρτωση των class libraries. Το JVM χρησιμοποιεί έναν γενικής χρήσης class loader για την φόρτωση των κλάσεων της εφαρμογής συνήθως τύπου java.net.urlclassloader. Δεν είναι σύνηθες να απαιτείται η συγγραφή class loader από τον προγραμματιστή. 13
Η δομή της εσωτερικής μνήμης του JVM Method area: αποθήκευση των κλάσεων και των σχετικών τους πληροφοριών μέθοδοι, πεδία, υπερ κλάσεις, κτλ.. Heap area: αποθήκευση όλων των αντικειμένων / στιγμιοτύπων. Language stacks: κάθε thread έχει τη δική του στοίβα, όπου αποθηκεύονται τοπικές μεταβλητές, ενδιάμεσα αποτελέσματα, κτλ σε μορφή stack frames. PC registers: Program counter register που περιέχει τη διεύθυνση του υπό εκτέλεση bytecode instruction. Native method stacks: αποθηκεύονται όλες οι native μέθοδοι της εφαρμογής. 14
Πρόταση για την τρίτη εργασία Java Threading & Concurrency 15
Η μηχανή εκτέλεσης του JVM Εκτέλεση του bytecode. Διερμηνέας / interpreter. Εκτέλεση γραμμή γραμμή. Just in time μεταγλωττιστής / compiler. Μεταγλώττιση του bytecode σε native κώδικα ανάλογα με τη χρήση. Δραστική βελτίωση στην απόδοση. Garbage collector. Εκτελείται στο παρασκήνιο και απελευθερώνει/διαχειρίζεται τη μνήμη της εφαρμογής heap. 16
To JVM Heap Όλα τα αντικείμενα αποθηκεύονται στο Heap. 17
Όλα μα όλα τα αντικείμενα java.lang.outofmemoryerror συνήθως λόγω μη διαθέσιμου ελεύθερου χώρου στο Heap Ειδικές παράμετροι στην εκκίνηση του JVM Ελάχιστο heap size: Xms512M Μέγιστο heap size: Xmx2048M 18
Το JVM διαχειρίζεται το Heap Με διάφανο για τον προγραμματιστή τρόπο. Αυτόματη δέσμευση και αποδεύσμευση μνήμης pointers. Αυτόματοι έλεγχοι εύρους buffer overflows & underflows. Garbage collection: αυτόματη απελευθέρωση μνήμης των αντικειμένων που δε χρησιμοποιούνται πλέον από το πρόγραμμα. 19
Garbage collection Θεμελιώδης έννοια: reachability of references/objects. Διάφοροι αλγόριθμοι: καταμέτρησης αναφορών, σημείωσης και εκκαθάρισης, σειριακοί, παράλληλοι, με ολική παύση του προγράμματος stop the world, με συμπύκνωση της θρυμματισμένης μνήμης, με έμφαση στην ταχύτητα δέσμευσης/αποδέσμευσης. 20
Στα σύγχρονα JVM Generational Garbage Collector 21
Βασική ιδέα Κατηγοριοποίηση των αντικειμένων με βάση τη "γενιά" τους. Τα περισσότερα αντικείμενα "πεθαίνουν νέα". Κάποια, λίγα, αντικείμενα "ζουν" για πολύ μεγάλα διαστήματα. Σπάνια τα "παλιά" αντικείμενα αναφέρονται σε "νέα". Μετακίνησή των αντικειμένων από τις νεότερες στις παλαιότερες γενιές ανάλογα με το πόσες "συλλογές/ εκτελέσεις" του GC έχουν καταφέρει να επιβιώσουν. Ταχύτερη συλλογή χώρου από τις νέες γενιές: μικρότερες παύσεις. 22
Πρόταση για την τρίτη εργασία Garbage Collection αλγόριθμοι 23
Εκτέλεση του JVM $ java cp CLASSPATH package.of.mainclass $ java jar app.jar Classpath: λίστα από τοποθεσίες που περιέχουν.class αρχεία συνήθως φάκελοι ή jar αρχεία MainClass: το πλήρες όνομα της κλάσης που περιέχει την main μέθοδο Jar file: αρχείο zip με κλάσεις.class και λοιπά στοιχεία λειτουργίας manifests, resources, κ.ά 24
Java packages και δομή καταλόγων package ys09.test; class Main {... } src ys09 test Main.java build ys09 test Main.class Θα επανέλθουμε σε άλλη διάλεξη 25
JVM Γλώσσες 26
Java Main.java class Main { public static void main(string[] args) { System.out.println("Hello world"); } } $ javac Main.java //μεταγλώττιση σε JVM bytecode (.class) $ java cp. Main //εκτέλεση του JVM με όρισμα τη Main κλάση Hello world 27
Scala Main.scala object Main { def main(args: Array[String]) { println("hello, world!") } } $ scalac Main.scala $ java cp.:scala library.jar Main Hello world $ scala Main Hello world 28
Scala scripts main.sh #!/usr/bin/env scala object HelloWorld extends App { println("hello, world!") } HelloWorld.main(args) $./main.sh Hello world 29
Groovy Main.groovy class Main { static void main(string[] args) { println("hello world") } } $ groovyc Main.groovy $ java cp.:groovy all.jar Main Hello world 30
Groovy scripts Main2.groovy println "Hello world" $ groovy Main2.groovy Hello world $ groovyc Main2.groovy $ java cp.:groovy all.jar Main2 Hello world Αλλά και $ groovy Main.groovy Hello world 31
JRuby main.rb puts "Hello world" $ jrubyc main.rb $ java cp.:various ruby.jars main Hello world $ jruby main.rb Hello world 32
Πρόταση για την τρίτη εργασία Σύγκριση Java Scala Ruby Python Groovy Kotlin Παρουσίαση της ECMAScript 6 νέα έκδοση Javascript 33
Για πληρότητα Η γλώσσα Java είναι statically typed, το JVM bytecode όχι. Με τη Java 7 έχουμε καλύτερη και ταχύτερη υποστήριξη για δυναμικές γλώσσες. invokedynamic: νέα εντολή bytecode για δυναμικές γλώσσες dynamically typed signatures or return types. 34