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

C# WPF WebBrowser Memory leak!


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

Δημοσ.

Καλησπέρα,

 

Φτιάχνω μια εφαρμογή σε WPF(C#), η εφαρμογή αυτή έχει το κύριο παράθυρο(1) που φορτώνει Controls

 

Συγκεκριμένα: Όλες οι φόρμες της εφαρμογής είναι ξεχωριστά Controls και πολύ απλά φορτώνω δυναμικά στην κύρια φόρμα το ανάλογο Control.

 

Όλες οι φόρμες(Controls) δουλεύουν σωστά εκτός από το Control που έχει τον WebBrowser.

 

Παρατήρησα ότι μόνο το Control που έχει το WebBrowser δεν επιστρέφει την μνήμη... λογικά το WebBrowser έχει κάποια ιδιαιτερότητα και δεν επιστρέφει την μνήμη...

 

Κάποια λύση;

 

(1): Το MainWindow έχει ένα Grid που εκεί φιλοξενώ-εμφανίζω δυναμικά όλα τα Control.

 

 

 

Ελπίζω να με καταλάβατε!

 

 

Δημοσ.

Πριν μιλήσουμε για λύση θα πρέπει πρώτα να βρούμε πρόβλημα.

  1. Είναι πολύ απίθανο να παρατήρησες ότι ο WebBrowser δεν επιστρέφει τη μνήμη. Μάλλον παρατήρησες ότι το virtual size της process δεν ξαναεπιστρέφει σε προηγούμενη τιμή. Αυτό πρώτον δε σημαίνει σχεδόν τίποτα στην πράξη και δεύτερον υπάρχουν λόγοι που μπορεί να το προκαλούν οι οποίοι δεν έχουν καμία σχέση με το WebBrowser συγκεκριμένα.
  2. Ως συνέχεια του παραπάνω αλλά αρκετά σημαντικό για να σταθεί μόνο του, δοκίμασες να φτάσεις χρήση μνήμης 4-5-6 GB? Αν δε δοκίμασες, δεν ξέρεις αν υπάρχει leak.
  3. Αν υπάρχει leak, το πιθανότερο είναι ότι οφείλεται σε κάτι που κάνεις εσύ και έχει σαν αποτέλεσμα να μη γίνεται collect ο WebBrowser (π.χ. υπάρχει event handler σε κάποιο event του που δεν έχεις αφαιρέσει).

Οπότε, γίνε πολύ πιο συγκεκριμένος.

Δημοσ.

Ο webbrowser έχει μεγάλο θέμα με memory leak από μόνος του...

 

http://stackoverflow.com/questions/8302933/how-to-get-around-the-memory-leak-in-the-net-webbrowser-control

 

http://stackoverflow.com/questions/904478/how-to-fix-the-memory-leak-in-ie-webbrowser-control

 

δεν είχα καταφέρει να βρω λύση, όχι ότι πολύ ασχολήθηκα, μιας και το χρησιμοποίησα για data collect από site, οπότε ανά μισή ώρα απλά σταμάταγα και ξαναξεκινούσα το πρόγραμμα(με άλλο πρόγραμμα προφανώς) :P

 

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

 

από ότι θυμάμαι ακόμα και με dispose της φόρμας καθώς και του control, και με garbage collect δεν μαζεύεται, οπότε κατέληξα στο να το κλείνω..

 

λύση ίσως υπάρχει, έχε υπόψιν σου ότι έχεις πολύ διάβασμα και δοκιμές για να βρεις άκρη.

Δημοσ.

Ο webbrowser έχει μεγάλο θέμα με memory leak από μόνος του...

 

http://stackoverflow.com/questions/8302933/how-to-get-around-the-memory-leak-in-the-net-webbrowser-control

 

http://stackoverflow.com/questions/904478/how-to-fix-the-memory-leak-in-ie-webbrowser-control

 

δεν είχα καταφέρει να βρω λύση, όχι ότι πολύ ασχολήθηκα, μιας και το χρησιμοποίησα για data collect από site, οπότε ανά μισή ώρα απλά σταμάταγα και ξαναξεκινούσα το πρόγραμμα(με άλλο πρόγραμμα προφανώς) :P

 

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

 

από ότι θυμάμαι ακόμα και με dispose της φόρμας καθώς και του control, και με garbage collect δεν μαζεύεται, οπότε κατέληξα στο να το κλείνω..

 

λύση ίσως υπάρχει, έχε υπόψιν σου ότι έχεις πολύ διάβασμα και δοκιμές για να βρεις άκρη.

   Βασικα μιας και θεωρω οτι θα ειναι το ιδιο ακριβως με το Webbroswer στην Delphi, και στηριζεται στον Ιντερνετ εξπλορερ, θα σου ελεγα να το γυρισεις στο TChromium Component, που σε μενα που ειχα θεματα με το Webbroswer και javascript ειχε κανει θαυματα.

Δημοσ. (επεξεργασμένο)

Ξέρετε αν υπάρχει κάποιος άλλος WebBrowser (Web Browser Engine) ΓΙΑ WPF;

 

δοκίμασα αυτό: https://code.google.com/p/geckofx/downloads/list

αλλά είναι μικρή Ιστορία(δεν είναι για WPF, { αν και μπορούμε να φιλοξενίσουμε Windows Controls σε WPF } ) και το άφησα.


Πριν μιλήσουμε για λύση θα πρέπει πρώτα να βρούμε πρόβλημα.

  1. Είναι πολύ απίθανο να παρατήρησες ότι ο WebBrowser δεν επιστρέφει τη μνήμη. Μάλλον παρατήρησες ότι το virtual size της process δεν ξαναεπιστρέφει σε προηγούμενη τιμή. Αυτό πρώτον δε σημαίνει σχεδόν τίποτα στην πράξη και δεύτερον υπάρχουν λόγοι που μπορεί να το προκαλούν οι οποίοι δεν έχουν καμία σχέση με το WebBrowser συγκεκριμένα.
  2. Ως συνέχεια του παραπάνω αλλά αρκετά σημαντικό για να σταθεί μόνο του, δοκίμασες να φτάσεις χρήση μνήμης 4-5-6 GB? Αν δε δοκίμασες, δεν ξέρεις αν υπάρχει leak.
  3. Αν υπάρχει leak, το πιθανότερο είναι ότι οφείλεται σε κάτι που κάνεις εσύ και έχει σαν αποτέλεσμα να μη γίνεται collect ο WebBrowser (π.χ. υπάρχει event handler σε κάποιο event του που δεν έχεις αφαιρέσει).

Οπότε, γίνε πολύ πιο συγκεκριμένος.

 

Από 50~ ΜΒ η διεργασία, την πήγα 380 (όπου βαρέθηκα και σταμάτησα)... άλλαζα συνεχώς τις καρτέλες (κάποια άσχετη καρτέλα με την καρτέλα που έχει το WebBrowser)

 

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

 

Ίσως πρέπει να του πούμε εμείς ότι δεν τα χρειαζόμαστε άλλο τα δεδομένα και να τα ξεφορτωθεί... αλλά πώς!

 

Νομίζω πως έφτιαξε... απλά έβαλα όταν ξεφορτώνει (UserControl_Unloaded) να κάνει webBrowser.Dispose().

Επεξ/σία από sonyxp
Δημοσ.

Αν υπάρχει leak, το πιθανότερο είναι ότι οφείλεται σε κάτι που κάνεις εσύ και έχει σαν αποτέλεσμα να μη γίνεται collect ο WebBrowser (π.χ. υπάρχει event handler σε κάποιο event του που δεν έχεις αφαιρέσει).

 

Μια απορια. Αν δεν αφαιρεσουμε (-=) το event handler και κλεισουμε την εφαρμογη θα εχουμε memory leak;

Αν ναι αυτο συμβαινει σε WPF & WinForms;

Δημοσ.

Μια απορια. Αν δεν αφαιρεσουμε (-=) το event handler και κλεισουμε την εφαρμογη θα εχουμε memory leak;

Αν ναι αυτο συμβαινει σε WPF & WinForms;

Οταν κλείσει η εφαρμογή δεν μενει τιποτα.

  • Like 1
Δημοσ.

Και γενικά, σε μοντέρνα λειτουργικά συστήματα (δηλαδή τα τελευταία 20-25 χρόνια) η έννοια του leak υφίσταται μόνο κατά τη διάρκεια της εκτέλεσης της εφαρμογής. Δεν είναι δηλαδή να πεις ότι "όταν κλείσει η εφαρμογή τα leaks τακτοποιούνται", αλλά "όταν κλείσει η εφαρμογή η λέξη leak δεν έχει νόημα".

Δημοσ.

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

 

Και δεδομένου πως εδώ το θέμα ήταν ότι δεν κάνουμε dispose το IDisposable, ο πρώτος κανόνας ισχύει.

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

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

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

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

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

Σύνδεση

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

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