Πώς να ξεφορτώσει την κατηγορία της Ιάβας
Έχω υποβληθεί αυτήν την ερώτηση αρκετές φορές. Πρόσφατα Xyling υπέβαλε την ίδια ερώτηση στο blog του. Έτσι σκέφτηκα ότι μια απλή εξήγηση μπορεί να είναι στη διαταγή.
Για να ξεφορτώσετε μια κατηγορία πρέπει να δημιουργήσετε μια συνήθεια classloader και να φορτώσετε την κατηγορία χρησιμοποιώντας το. Το Tomcat το κάνει και κάνει έτσι JRun. Μπορείτε να κοιτάξετε στον κώδικα Tomcat για ένα παράδειγμα.
Αφότου γίνεστε με την κατηγορία πρέπει να απελευθερώσετε όλες τις αναφορές στην κατηγορία καθώς επίσης και στο φορτωτή κατηγορίας με την επανεκχώρηση των μεταβλητών ή τη ρύθμιση τους που αχρηστεύουν.
Κατόπιν είτε περιμένετε System.gc () να ξεφορτώσετε την κατηγορία ή το καλείτε άμεσα μέσα βρόχο μέχρης ότου δεν μπορούν να ελευθερωθούν άλλες ψηφιολέξεις. εντούτοις καλώντας κανονικά κάνει δύο φορές το τέχνασμα.
Σημείωση: Δεν μπορείτε να ξεφορτώσετε μια ενιαία κατηγορία. Πρέπει να ξεφορτώσετε το classloader μαζί με το. Τόσο προφανώς το σύστημα classloader δεν είναι το κατάλληλο για αυτόν τον στόχο.
Σημείωση 2: Έτσι οι σελίδες JSP ξαναφορτώνονται δυναμικά everytime εσείς αλλάζουν τον κώδικα. Και ναι γίαυτό ο πρώτος χρόνος παίρνει πολύ περισσότερο για να φορτώσει έπειτα τους επόμενους χρόνους.
_ Filed κατώτερος πώς, Ιάβα λογισμικό, τεχνολογία |
|
RSS 2.0 |
Ηλεκτρονικό ταχυδρομείο αυτό το άρθρο
Μπορείτε επίσης να επιθυμήσετε να διαβάσετε |


Προσθέστε στις συμπάθειες Technorati


































15η Μαρτίου 2005 στις 6:31 μ.μ.
Γεια,
Σας ευχαριστούμε πάρα πολύ για αυτές τις πληροφορίες.
Απασχολήστε εάν επεκτείνω την ερώτησή μου εδώ ο ίδιος; Πραγματικά, φορτώνω τις κατηγορίες μου μέσω URLClassLoader. Και γενικά φορτώνω τα αρχεία ΒΑΖΩΝ μέσω URLClassLoader. Τώρα θέλω αυτό το αρχείο ΒΑΖΩΝ για να ξεφορτωθώ. Μπορώ να επεκτείνω τη λογική σας σε URLClassLoader για τα αρχεία ΒΑΖΩΝ επίσης;
15η Μαρτίου 2005 στις 6:33 μ.μ.
Σας ευχαριστούμε.
15η Μαρτίου 2005 στις 6:41 μ.μ.
Πραγματικά, ο χρόνος πρώτος-φορτίων JSP οφείλεται όχι μόνο στην κατηγορία που ξαναφορτώνεται, (η φόρτωση μιας κατηγορίας από το bytecode δεν παίρνει αυτού πολύ, εάν έκανε την Ιάβα θα ήταν πολύ πιό αργή από είναι -). Μια περισσότερο σημαντική ποσότητα του χρόνου ξοδεύεται παράγοντας το bytecode, δεδομένου ότι μια αλλαγή στην πηγή JSP πρέπει να μετατραπεί πρώτα στην πηγή της Ιάβας, και έπειτα μέσα στον ψηφιολέξη-κώδικα, ο οποίος μπορεί έπειτα να φορτωθεί από το ClassLoader. Έτσι, προσθέστε ότι δύο αναλύουν/παράγουν τους κύκλους σε ένα φορτίο ψηφιολέξεων…
16η Μαρτίου 2005 στις 4:28 μ.μ.
Εάν ενδιαφέρεστε για να δείτε μια ενδιαφέρουσα συστροφή στο δυναμικό ξαναφόρτωμα των κατηγοριών, ελέγξτε έξω την πηγή στη μηχανή plugin μας στο http://www.platonos.org. Όχι μόνο φορτώνουμε plugins, κάθε ένας με το classloader τους, αλλά προσθέτουμε τώρα τη δυνατότητα να ξεφορτώσουμε δυναμικά τις μερίδες ενός plugin που εξαρτώνται από άλλο.
Όπως βγάζει, όταν plugin παρέχει το Α μια διεπαφή ότι plugin το Β παρέχει μια εφαρμογή για, το plugin Β ClassLoader (μέσω της αντιπροσωπείας στο classloader του Α) κρατά μια κλειδαριά η ίδια στην κατηγορία εφαρμογής. Ακόμα και αφού αχρηστεύουμε έξω το classloader στο plugin Α (εάν προσπαθούμε να ξεφορτώσουμε το Α), τα β classloader κρατούν μια κλειδαριά στο Α λόγω της κατηγορίας διεπαφών ότι η κατηγορία εφαρμογής του β κρατά μια κλειδαριά επάνω. Βασικά έχετε αυτό:
διεπαφή pluginAInterface {}
η κατηγορία pluginBImpl εφαρμόζει pluginAInterface {}
κάθε ένας φορτώνεται από ένα διαφορετικό classloader. Όταν χρησιμοποιούνται, plugin τα β classloader βλέπουν ότι pluginBImpl εφαρμόζει pluginAInterface. Αρχίζει στο plugin β classloader ψάχνοντας το. Δεν μπορεί να το βρεί εκεί (επειδή η κατηγορία pluginAInterface είναι στο classloader plugin Α classpath). Οι εκπρόσωποι μηχανών plugin η συμβούλευση στο classloader plugin Α για να βρεί τον κώδικα ψηφιολέξεων για αυτήν την κατηγορία pluginAInterface. Έχει βρεί εκεί, έτσι plugin το classloader του Α «φορτώνει» το bytecode, αλλά plugin τα β classloader «βλέπουν» το bytecode με αρχικά να εξουσιοδοτήσουν στο Α για να το βρούν. Βρήκε, classloader που χτίστηκαν στα καταστήματα κρύπτης το classloader: ο δείκτης κατηγορίας (η σημασία, το classloader ΚΑΙ η κατηγορία αποτελούν κάποιο «κλειδί» ως δείκτη στο πραγματικό bytecode στη μνήμη) έτσι αυτό δεν χρειάζεται πλέον στον εκπρόσωπο στο Α. ΑΛΛΆ, το μεγάλο πρόβλημα είναι ότι η κατηγορία pluginBImpl διατηρεί είναι κατάλογος διεπαφών εφαρμόζει, πρώτιστα η αναφορά κατηγορίας τους. Το κακό πράγμα για αυτό δεν είναι είναι εκεί κανένας τρόπος να τεθεί αυτό που αχρηστεύει στο χρόνο εκτέλεσης!
Έτσι το τέχνασμά μας είναι να χρησιμοποιήσουμε έναν δεύτερο classloader μέσα σε ένα plugin για να επιτρέψει ότι κάθε διεπαφή που εφαρμόζεται από ένα άλλο plugin που έχει αυτό είναι classloader έτσι μπορούμε να απορρίψουμε εκείνο το ένα για να πάρουμε το ξαναφόρτωμα/την εκφόρτωση για να εργαστούμε.
Είναι λίγο δυσνόητο, αλλά κάνει το τέχνασμα. Πιθανώς κρυμμένα ακόμη μερικά ζητήματα δεν έχουμε συναντήσει τυχαία ακόμα.
18η Μαρτίου 2005 στις 3:00 AM
@Goldy Lukka ναι. Πρέπει να είστε σε θέση. Εντούτοις δεν έχω χρησιμοποιήσει URLClassLoader με αυτό τον τρόπο, έτσι δεν είμαι βέβαιος εάν έχει οποιους δήποτε να σκληρός--αφαιρέσουν τις αναφορές. Υποθέτω ότι μια λύση ακίδων είναι στη διαταγή
BTW: Απολαμβάνω την περιοχή σας.
ευχαριστίες @Kevin για το πολύ πληροφοριακό σχόλιο.
19η Μαρτίου 2005 στις 2:54 AM
Goldy Lukka,
Το τέχνασμα στη χρησιμοποίηση URLClassLoader για να ξαναφορτώσει ή να ξεφορτώσει .jar τα αρχεία σιγουρεύεται ότι ΚΑΝΕΝΑΣ άλλος κώδικας δεν παραπέμπει οποιων δήποτε από τις κατηγορίες μέσα στο .jar αρχείο. Οι εξαρτήσεις είναι δύσκολο να διαχειριστούν. Έχουμε πάει στους μεγάλους πόνους να προσπαθήσουμε να επιλύσουμε ξεφορτώνουμε/ξαναφορτώνουμε με το ζήτημα των plugins ανάλογα με το ένα άλλο. Έχουμε ακόμα τα προβλήματα που κάνουν σε πολλές περιπτώσεις το να συμβεί. Σε μερικές περιπτώσεις, οι υπεύθυνοι για την ανάπτυξη των plugins πρέπει ακριβώς να γνωρίσουν ότι εάν θέλουν να καταστήσουν το plugin τους όσο το δυνατόν δυναμικότερο, πρέπει πραγματικά να το αναπτύξουν κατά τέτοιο τρόπο ώστε καθαρίζουν κατάλληλα επάνω οποιεσδήποτε αναφορές που έχουν σε άλλες κατηγορίες plugin.
Εάν .jar το αρχείο σας προσθέτει ακριβώς τις εφαρμογές που λένε, μια διεπαφή API εφαρμογών πυρήνων, εσείς πρέπει να είναι σε θέση να την αφαιρέσει εύκολα. Όπως ανακαλύψαμε, μια implemting κατηγορία κρατά μια αναφορά (κλειδαριά) στη διεπαφή που εφαρμόζει. Έτσι η κατηγορία .jar στο αρχείο σας θα τηρούσε το REF τη διεπαφή, που είναι εντάξει, εσείς το αχρηστεύει απλά έξω ή/και αχρηστεύει το classloader που φόρτωσε .jar και είστε λεπτοί. Εάν εντούτοις το .jar αρχείο παρέχει τις διεπαφές που άλλες κατηγορίες (ίσως από άλλα .jar αρχεία) χρησιμοποιούν, αυτό γίνεται δυσκολότερο. Οποιαδήποτε κατηγορία έξω από το classloader που φόρτωσε το .jar αρχείο χρησιμοποιώντας οποιαδήποτε κατηγορία από μέσα από φορτωμένο .jar πρέπει επίσης να ξεφορτωθεί. Πάλι, αναφερόμενος στη μηχανή μας, αρχίζει μια αλυσωτή αντίδραση των γεγονότων εκφόρτωσης που μπορεί να είναι δύσκολο να διαχειριστεί. Λύσαμε το πρόβλημα από την κατοχή δύο περιπτώσεων classloader ανά plugin. Ένας που χειρίζεται τις διεπαφές που εφαρμόζονται από άλλες κατηγορίες plugin, και μια για το υπόλοιπο των κατηγοριών. Δεν είναι όμορφο, αλλά ως εδώ λειτουργεί. Πειραματιζόμαστε ακόμα για να κάνουμε αυτό μια καλύτερη διαδικασία.
22η Μαρτίου 2005 στις 7:35 μ.μ.
Kevin,
Είναι αλήθεια ότι δεν μπορείτε να αχρηστεύσετε την αναφορά στην κατηγορία διεπαφών (Class#getInterfaces ()), εάν αυτό ήταν δυνατό θα σήμαινε ότι αφαιρείτε τη διεπαφή στον κώδικα ψηφιολέξεων στο χρόνο εκτέλεσης, από:
δημόσια μέσα TestImpl MyTestImpl κατηγορίας
{
}
δημόσια κατηγορία MyTestImpl
{
}
Το ίδιο πράγμα ισχύει για τα superclasses.
23η Μαρτίου 2005 στις 6:23 μ.μ.
είναι μεγάλες πληροφορίες ότι πώς plugins είναι εργασίες. Μπορώ να έχω τον απλούστερο πιθανό κώδικα του φορτωτή κατηγορίας συνήθειας. Τελικά ο φορτωτής κατηγορίας συνήθειας πρόκειται nees να φορτωθεί από την προεπιλογή classloader ή όχι; Εάν τόσο έπειτα θα είμαι σε θέση να δω στο classloader στο callgraph τέτοιου είδους προγράμματος;
1η Απριλίου 2005 στις 6:02 AM
@Sandip γιατί να μην χρησιμοποιήσει το URLClassLoader; Επίσης υπάρχει ένας κώδικας ClassLoader δειγμάτων που παρέχεται στα σεμινάρια της Ιάβας.
11η Σεπτεμβρίου 2006 στις 11:39 AM
Ευχαριστίες για τις πληροφορίες.
Διάβασα κάτι στο διαδίκτυο που σκέφτομαι είναι σημαντικό για μερικούς ανθρώπους εδώ:
Δύο κατηγορίες δεν είναι της ίδιας συσκευασίας εάν φορτώνονται από τα διαφορετικά αντικείμενα ClassLoader!
Πέστε ότι έχετε μια συσκευασία με δύο κατηγορίες, κάποια είναι δημόσια και άλλη συσκευασία-ιδιωτική. Αυτοί πρέπει να φορτωθούν από το ίδιες (ή την υποκατηγορία) αντικείμενο ClassLoader. Εάν εσείς δεν παίρνετε ένα λάθος χρόνου εκτέλεσης όταν προσπαθεί να έχει πρόσβαση η δημόσια κατηγορία στη συσκευασία-ιδιωτική κατηγορία.
Έτσι εάν προγραμματίσατε να κάνετε ένα νέο αντικείμενο ClassLoader για κάθε κατηγορία, θεωρήστε ένα αντικείμενο ClassLoader για κάθε συσκευασία. Η άλλη επιλογή είναι να γίνει όλο το κοινό κατηγοριών.