Προς το περιεχόμενο

Μεγάλο πρόγραμμα σε Java + παλιός υπολογιστής = κόλλημα


yincyun

Προτεινόμενες αναρτήσεις

Καλησπέρα,

 

Κάνω ένα project σε java το οποίο είναι αρκετά μεγάλο και με πολλές επαναλήψεις και εντός του προγράμματος και στην εκτέλεση την ίδια, όπως επίσης και τα αρχεία που παράγει και στη συνέχεια χρησιμοποιεί (έως 1G το συνολικό μέγεθος όλων των αρχείων).

 

Ο υπολογιστής στον οποίο πρέπει να τρέξω το συγκεκριμένο πρόγραμμα - που κάνει μια μεγάλη προσομοίωση αν μπορώ να το πω έτσι - είναι αρκετά παλιός με 1G ram από την οποία μνήμη συνήθως τα 2/3 είναι κατειλημμένα από το ίδιο το λειτουργικό.

 

Δεν είμαι κάποιος σπουδαίος προγραμματιστής αλλά προσπάθησα να βγάλω από το πρόγραμμά μου ότι "αχρείαστο" υπάρχει ώστε να το κάνω πιο γρήγορο αρχικά και να μην κολλάει στην συνέχεια. Επίσης προσπάθησα να ελαττώσω τη χρήση πολλών μεταβλητών και αντικειμένων και να επαναχρησιμοποιώ όσο μπορώ τα υπάρχοντα. 

 

Για παράδειγμα μια εκτέλεση στο συγκεκριμένο μηχάνημα μπορεί να κρατήσει και 2 μέρες σε μια μεσαίου μεγέθους προσομοίωση.

 

Δυστυχώς δεν είναι δυνατή ούτε η αντικατάσταση του υπολογιστή ούτε των καρτών μνήμης για διάφορους λόγους.

 

Τι μπορώ να κάνω προγραμματιστικά ώστε να το βοηθήσω να "αδειάζει/ελευθερώνει" ίσως τη μνήμη που χρησιμοποιεί για την επόμενη εκτέλεσή του ή έστω να μη κολλάει κατά την εκτέλεση και συνεχίζει όποτε "θυμάται";

 

Ευχαριστώ για τις απαντήσεις.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Moderators

 

Welcome to Java lol

 

 

Το έχεις περάσει από profiler; Το τι μπορείς να κάνεις δε νομίζω να μπορεί να στο πει κανείς χωρίς κώδικα, πέρα από ίσως γενικά πράγματα.

 

http://java-performance.com/

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κράτα στη μνήμη μόνο ότι χρειάζεται για το βήμα που είσαι. Σε παλιό υπολογιστή το swaping παίρνει παραπάνω από το να γράφεις σε αρχείο ότι δε χρειάζεσαι, αποδεςμευεις τη μνήμη, και το εισάγεις όταν το ξαναχρειαστείς.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

Welcome to Java lol

 

 

Το έχεις περάσει από profiler; Το τι μπορείς να κάνεις δε νομίζω να μπορεί να στο πει κανείς χωρίς κώδικα, πέρα από ίσως γενικά πράγματα.

 

http://java-performance.com/

 

Δεν γνωρίζω καν για το profiler αλλά θα το ψάξω αύριο με καθαρό μυαλό. Όπως επίσης και το link που παρέθεσες.

 

Δεν μπορώ να δείξω κώδικα καθώς είναι τεράστιος και δεν νομίζω ότι θα βοηθήσει και στο πρόβλημά μου μιας και ο κώδικας σαν κώδικας δεν είναι πρόβλημα δουλεύει απλά τερματίζει το τρέξιμο του αργά. Επίσης να πω ότι επειδή είναι προσομοίωση άλλες φορές είναι πιο αργή και άλλες πιο γρήγορη. Το θέμα μου είναι στα κολλήματα που τρώει. Σαν να ξεχνάει να συνεχίσει το τρέξιμό του.

 

Ψιτ : Το έχω κάνει αυτό που προτείνεις όσο μπορώ.

 

 

Αυτό που φαντάζομαι ότι ψάχνω είναι μια ίσως System εντολή είτε κάποια ιδέα πως να το κάνω να μη κολλάει με τη μνήμη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Συνδέσου με jconsole (υπάρχει διαθέσιμο στο bin folder της Java εγκατάστασης σου) να δεις τα stats την ώρα την εκτέλεσης. Εκεί θα δεις καλύτερα πως διαχειρίζεται την μνήμη και πόσο cpu usage έχεις.

 

Το να μην κολλάει με την μνήμη, ίσως χρειαστεί να παίξεις με τις παραμέτρους που περνάς στο jvm κατά την έναρξη της εκτέλεσης (heap size, κλπ.). Ίσως σε βοηθήσει να πειραματιστείς και ποιον garbage collector θα χρησιμοποιεί η εφαρμογή.

 

Επίσης, μπορείς να δοκιμάσεις System.gc() για να να προχωρήσει το σύστημα σε garbage collection όσο πιο σύντομα μπορεί.

 

Good luck.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ιδέα...απλά!

1. Αν είναι ανάγκη να χρησιμοποιηθούν μεγάλοι πίνακες μπορεί κανείς να κάνει αρχείο και να φορτώνει σελίδες του πίνακα. Εκεί που θα διάβαζε το πίνακα απευθείας θα τσεκάρει αν υπάρχει το κομμάτι στη μνήμη, αν δεν υπάρχει το φέρνει γράφοντας το υπάρχον πίσω στο αρχείο. Για να πετύχει η δουλειά πρέπει η εργασία να δουλεύει σε τμήματα. Αν το καταφέρει κανείς αυτό πάει στο επόμενο βήμα...να βάλει δυο υπολογιστές να δουλεύουν  παράλληλα για ίδιο αρχείο.

2. Αν κάθε φορά φτιάχνεις νέο αντικείμενο προσωρινό, ενώ δεν υπάρχει ανάγκη (δεν έχουμε αναδρομική κλήση και δεν υπάρχει περίπτωση reentrance), θα χάνεις πολύ χρόνο στην "καταστροφή του". Τότε χρησιμοποιούμε γενικό αντικείμενο (δεν έχει γενικές/σφαιρικές η java, κάνεις ένα public class, αλλά εδώ μάλλον αυτό χρειάζεσαι). Είναι καλύτερα να φορτώνουμε τιμές στο αντικείμενο παρά να κάνουμε νέο και να το καταστρέφουμε συνέχεια (σε μερικές γλώσσες η καταστροφή απαιτεί δεκαπλάσιο χρόνο από τη δημιουργία).

3. Αν κάνει κανείς συνέχεια casting προφανώς βάζει επιπλέον δουλεία στο runtime.

4. Αν υπάρχει πρόγραμμα για ιους προφανώς πρέπει να βγει εκτός. Ακόμα και το index για τα αρχεία στο δίσκο (που υποτίθεται ότι ψάχνεις να βρεις πιο γρήγορα κάτι, μια φορά να το κάνεις...αλλά αυτό δουλεύει ασταμάτητα..)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

 

Πολλοί ας πούμε από συνήθεια αν θέλουμε ακέραιους γράφουμε int, ακόμα και αν οι πιθανές τιμές που περιμένουμε είναι μικρές, ακόμα και από το 1 έως το 10.

Ένας int όμως είναι 32bit, και ένα byte είναι 8bit. Και ένα short είναι 16bit.

Παρομοίως ίσως να μη χρειάζεσαι τόσο μεγάλη ακρίβεια όση παρέχει μια double, και να μπορείς να χρησιμοποιήσεις float σε κάποιες περιπτώσεις.

 

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

 

Σε ένα πολύ μικρότερο δικό μου πρόγραμμα, δοκίμασα να κάνω αυτό που περιέγραψα, και από 3.7mb το runtime έπεσε στα 3.5mb. 

Βέβαια το πόσο μεγάλο θα είναι το όφελος εξαρτάται και από το πρόγραμμα...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Moderators

Επίσης, μπορείς να δοκιμάσεις System.gc() για να να προχωρήσει το σύστημα σε garbage collection όσο πιο σύντομα μπορεί.

 

Χτες που καθόμουν κι έψαχνα γι αυτό το θέμα είδα και αυτό και είπα να μην το προτείνω. Όμως σε άλλες απαντήσεις λένε και περιπτώσεις που μπορεί να θες να καλέσεις απευθείας τον gc. Απ' αυτό που γράφεις φαντάζομαι δε θεωρείς πρόβλημα να καλείς τον gc, μπορείς λίγο να μου εξηγήσεις γιατί;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αν ο υπολογιστής τρέχει windows, βάλε του μια lightweight linux διανομή ώστε να έχεις όση περισσότερη μνήμη ελεύθερη γίνεται

 

Linux mint 17.2

 

Συνδέσου με jconsole (υπάρχει διαθέσιμο στο bin folder της Java εγκατάστασης σου) να δεις τα stats την ώρα την εκτέλεσης. Εκεί θα δεις καλύτερα πως διαχειρίζεται την μνήμη και πόσο cpu usage έχεις.

 

Το να μην κολλάει με την μνήμη, ίσως χρειαστεί να παίξεις με τις παραμέτρους που περνάς στο jvm κατά την έναρξη της εκτέλεσης (heap size, κλπ.). Ίσως σε βοηθήσει να πειραματιστείς και ποιον garbage collector θα χρησιμοποιεί η εφαρμογή.

 

Επίσης, μπορείς να δοκιμάσεις System.gc() για να να προχωρήσει το σύστημα σε garbage collection όσο πιο σύντομα μπορεί.

 

Good luck.

 

Το δοκίμασα το System.gc() χωρίς ιδιαίτερη επιτυχία. Το βρήκα σε κάποια samples στο google και προσπάθησα να το εφαρμόσω και πιστεύω δεν βοήθησε.

 

Ιδέα...απλά!

1. Αν είναι ανάγκη να χρησιμοποιηθούν μεγάλοι πίνακες μπορεί κανείς να κάνει αρχείο και να φορτώνει σελίδες του πίνακα. Εκεί που θα διάβαζε το πίνακα απευθείας θα τσεκάρει αν υπάρχει το κομμάτι στη μνήμη, αν δεν υπάρχει το φέρνει γράφοντας το υπάρχον πίσω στο αρχείο. Για να πετύχει η δουλειά πρέπει η εργασία να δουλεύει σε τμήματα. Αν το καταφέρει κανείς αυτό πάει στο επόμενο βήμα...να βάλει δυο υπολογιστές να δουλεύουν  παράλληλα για ίδιο αρχείο.

2. Αν κάθε φορά φτιάχνεις νέο αντικείμενο προσωρινό, ενώ δεν υπάρχει ανάγκη (δεν έχουμε αναδρομική κλήση και δεν υπάρχει περίπτωση reentrance), θα χάνεις πολύ χρόνο στην "καταστροφή του". Τότε χρησιμοποιούμε γενικό αντικείμενο (δεν έχει γενικές/σφαιρικές η java, κάνεις ένα public class, αλλά εδώ μάλλον αυτό χρειάζεσαι). Είναι καλύτερα να φορτώνουμε τιμές στο αντικείμενο παρά να κάνουμε νέο και να το καταστρέφουμε συνέχεια (σε μερικές γλώσσες η καταστροφή απαιτεί δεκαπλάσιο χρόνο από τη δημιουργία).

3. Αν κάνει κανείς συνέχεια casting προφανώς βάζει επιπλέον δουλεία στο runtime.

4. Αν υπάρχει πρόγραμμα για ιους προφανώς πρέπει να βγει εκτός. Ακόμα και το index για τα αρχεία στο δίσκο (που υποτίθεται ότι ψάχνεις να βρεις πιο γρήγορα κάτι, μια φορά να το κάνεις...αλλά αυτό δουλεύει ασταμάτητα..)

1. Δεν χρησιμοποιώ πίνακες καθόλου.

2. Δεν φτιάχνω προσωρινά αντικείμενα. Στην αρχή το έκανα και ήταν ακόμα πιο αργό αλλά το έστρωσα. Επαναχρησιμοποιώ τα πάντα όσο γίνεται.

3. Δεν κάνω casting.

4. Linux και δεν υπάρχει κάποιο antivirus. 

 

Ευχαριστώ για τις προτάσεις!

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

 

Πολλοί ας πούμε από συνήθεια αν θέλουμε ακέραιους γράφουμε int, ακόμα και αν οι πιθανές τιμές που περιμένουμε είναι μικρές, ακόμα και από το 1 έως το 10.

Ένας int όμως είναι 32bit, και ένα byte είναι 8bit. Και ένα short είναι 16bit.

Παρομοίως ίσως να μη χρειάζεσαι τόσο μεγάλη ακρίβεια όση παρέχει μια double, και να μπορείς να χρησιμοποιήσεις float σε κάποιες περιπτώσεις.

 

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

 

Σε ένα πολύ μικρότερο δικό μου πρόγραμμα, δοκίμασα να κάνω αυτό που περιέγραψα, και από 3.7mb το runtime έπεσε στα 3.5mb. 

Βέβαια το πόσο μεγάλο θα είναι το όφελος εξαρτάται και από το πρόγραμμα...

 

Οκ κάποιες for είναι int και κάποιες πράξεις σε double αλλά κυρίως το πρόγραμμα επεξεργάζεται Strings ( γι' αυτό επέλεξα τη java να το κάνω καθώς τη γνωρίζω από τη σχολή μου σε κάπως μέτριο επίπεδο αν είναι για σοβαρή δουλειά ) οπότε δε μπορώ να το αλλάξω κάπως.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κανονικά ούτε εγώ θα το πρότεινα, απλά επειδή είναι λίγο περίεργη η κατάσταση το ανέφερα μπας και κατάφερνε να ελευθερώσει μνήμη πιο νωρίς σε διάφορα σημεία. Χωρίς να δούμε κώδικα/flow της εφαρμογής είναι λίγο στην τύχη. Thanks για το link πάντως.

 

Προφανώς υπάρχει γενικότερο θέμα για να φτάνεις σε αυτό το σημείο, αλλά δεν υπάρχει turning back από ότι φαίνεται με όλα τα limitations που έχουν τεθεί από τον OP.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κάνε profile όπως σου πρότειναν για να δεις αν έχεις αντικείμενα (λίστες, collections, set) που ξεχειλωνουν και σου τρώνε την μνήμη. Με το να αλλάξεις τους integer σε short δε νομίζω να σωθεις

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μιας και λες ότι παίζουν οι χρόνοι εκτέλεσης, τότε μιλάμε είτε για στοχαστικές διαδικασίες είτε για διαδικασίες που παίρνουν random input (π.χ user κτλ). 

 

 

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

 

Προσπάθησε να απομονώσεις το πρόβλημα. Είναι μνήμη; Είναι υπολογισμοί; Τι; 

 

Εάν είναι μνήμη, τότε από τι προκαλείται; Από φόρτωμα αρχείων; Από μεταβλητές; Εάν είναι από αρχεία, δες τα streams. Εάν είναι από μεταβλητές, οργάνωσε καλύτερα τον κώδικά σου. 

 

Εάν είναι υπολογισμοί, τότε σκέψου το ενδεχόμενο να χρησιμοποιήσεις τεχνικές vectorization ή στατικούς πίνακες αντί για List ή κάποιο library για fast math. 

 

Αλλά το "πάει αργά" δεν βοηθάει. Είναι σαν να λες στον γιατρό "πονάει η κοιλιά μου". 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...