Entwickler-Ecke
Sonstiges (.NET) - gleiches objekt mehrmals erstellen
uwe1234 - Mi 31.08.11 17:56
Titel: gleiches objekt mehrmals erstellen
Hallo zusammen,
ich habe eine einfache Frage.
C#-Quelltext
1: 2: 3: 4: 5: 6:
| private void button19_Click(object sender, EventArgs e) { Ware produkt1 = new Ware(); produkt1.Produkt = "TEST"; labelZA.Text = produkt1.Produkt; } |
Wenn ich den Button drücke wird das Objekt produkt1 erstellt usw. Was passiert mit dem Objekt wenn ich den Button
nochmals drücke. Laut meinem debugger wird das Objekt erneut erstellt oder sehe ich das falsch? Ist das ein Problem,
wenn auf diese Art das Objekt erneut erstellt wird?
Danke und Gruß
Uwe
Kha - Mi 31.08.11 18:01
new erstellt nunmal ein Objekt der angegebenen Klasse, also ja ;) . Auf das Objekt des letzten Klicks hast du keinen Zugriff, da du ja keine Referenz mehr hältst.
Was für Probleme stellst du dir denn vor? Zu einem Performance-Problem wird das jedenfalls erst, wenn du die Methode einmal pro Mikrosekunde ausführst.
Edit: Um es sprachlich noch einmal festzunageln: Es wird nicht das gleiche Objekt mehrmals erstellt, sondern Objekte (= Instanzen) der gleichen Klasse. Ebenso ist es nicht möglich, ein Objekt "erneut zu erstellen".
uwe1234 - Mi 31.08.11 18:37
Hallo,
ich habe mir die Punkte Destruktor, Garbage Collector und Dispose angeschaut. Dabei ist mir die Frage aufgekommen,
was mit den Objekten (Instanzen) bei meinem Beispiel passiert, wenn ich den Button mehrmals drücke. Was passiert mit den Instanzen bei denen die Referenz nicht mehr gehalten wird? Belegen diese z.B. Speicher etc.?
Ich möchte C# lernen, und vielleicht auch mal verstehen, und nicht nur irgendwelche Programmcodes die ich irgendwo her habe zusammenführen. Daher meine Frage.
Danke und Gruß
Kha - Mi 31.08.11 19:29
uwe1234 hat folgendes geschrieben : |
Was passiert mit den Instanzen bei denen die Referenz nicht mehr gehalten wird? |
Wenn wirklich keinerlei Referenz mehr existiert, ist das Objekt "eligible for garbage collection", wann auch immer diese dann passieren mag (nicht-deterministische Freigabe).
stes - Mi 31.08.11 22:26
Hallo,
nochmal zu deinen Fragen:
uwe1234 hat folgendes geschrieben : |
Dabei ist mir die Frage aufgekommen,
was mit den Objekten (Instanzen) bei meinem Beispiel passiert, wenn ich den Button mehrmals drücke. Was passiert mit den Instanzen bei denen die Referenz nicht mehr gehalten wird? Belegen diese z.B. Speicher etc.?
Danke und Gruß |
so wie du es machst belegt das ganze keinen zusätzlichen Speicher, da du dein Objekt ja quasi ständig mit einer neuen Instanz der Klasse überschreibst. Das "alte" Objekt muss dafür gewissermaßen den Platz räumen.
Anders ist es, wenn du die Objekte "aufbewahrst", z.B. in einer ArrayList speicherst. Hierzu zwei Beispiele:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| static void Main(string[] args) { while(true) { Object o = new Object(); } } |
Wenn du eine Konsolenanwendung mit dieser Hauptprozedur erstellst und dir den Prozess im Taskmanager anschaust, ist der Speicherbedarf der Anwendung (näherungsweise) konstant. Anders wenn du folgenden Code ausführst:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| static void Main(string[] args) { System.Collections.ArrayList list = new System.Collections.ArrayList(); while(true) { list.Add(new Object()); } } |
Wenn du dieses Programm ausführst und dir den Taskmanager anschaust, kannst du sehen wie der Speicherbedarf regelrecht in die Höhe schnellt (irgendwo ja logisch). Das ganze endet dann in einer OutOfMemoryException (bei mir bei ~1GB Speicherbedarf).
Weitere Infos zum Thema auch bei
VC# openbook, Kapitel "Zerstören von Objekten"/GC [
http://openbook.galileocomputing.de/visual_csharp_2010/visual_csharp_2010_04_008.htm#mj5c9073a7a50b2e0c07435459352f3a2b]
Gruß
stes
Kha - Mi 31.08.11 22:49
stes hat folgendes geschrieben : |
so wie du es machst belegt das ganze keinen zusätzlichen Speicher, da du dein Objekt ja quasi ständig mit einer neuen Instanz der Klasse überschreibst. Das "alte" Objekt muss dafür gewissermaßen den Platz räumen. |
Das stimmt einfach nicht. Es können beide Instanzen gleichzeitig im Speicher sein, wenn man zweimal nacheinander auf den Button drückt, ist das sogar relativ wahrscheinlich. Natürlich wird aber spätestens vor einer OOM-Exception eine Full Collection durchgeführt, den Speicher ganz füllen kann man sich damit nicht.
stes - Mi 31.08.11 23:27
Kha hat folgendes geschrieben : |
Das stimmt einfach nicht. Es können beide Instanzen gleichzeitig im Speicher sein, wenn man zweimal nacheinander auf den Button drückt, ist das sogar relativ wahrscheinlich. |
Ok ich sehe es ein :D Gerade einen Artikel gefunden:
Artikel über den Managed Heap in C# [
http://www.codeguru.com/columns/dotnet/article.php/c6593].
Demnach wäre es allerdings so (etwa bei meinem ersten Beispiel), dass die Objekte in der ersten Generation des managed heap hängen bleiben und relativ schnell (da wenig Speicher für die erste Generation reserviert ist) wieder vom GC aufgelesen werden, was darin resultiert, dass im Taskmanager keine Veränderungen am Speicherbedarf erkennbar sind, soweit sachlich korrekt? ;)
Gruß
stes
Kha - Mi 31.08.11 23:33
Dass sie Generation 0 nicht verlassen, kannst du nicht garantieren, aber ja, es ist sehr wahrscheinlich :) . Solche kurzlebigen Objekte haben GCs am liebsten.
stes - Mi 31.08.11 23:44
Kha hat folgendes geschrieben : |
Dass sie Generation 0 nicht verlassen, kannst du nicht garantieren, aber ja, es ist sehr wahrscheinlich |
Also ich könnte mir keinen "wahrscheinlicheren" Fall denken, als jenen beschriebenen bei dem der Variablen bei jeden Schleifendurchlauf direkt eine neue Instanz zuteil wird ^^
uwe1234 - Do 01.09.11 08:46
Das bedeutet für mich um es kurz zu fassen:
Instanzen (die die Referenz verloren haben) bleiben für eine unbestimmte Zeit im Speicher als "leichen" erhalten, bis der GC sie aufräumt, korrekt?
Durch welche Bedingungen verliert eine Instanz die Referenz, außer durch mein Beispiel?
dark-destination1988 - Do 01.09.11 10:05
lokales objekt in methode--> nach verlassen der methode
Th69 - Do 01.09.11 12:54
Und bei Containern durch z.B. list.Remove(object), d.h. wenn ein anderes Objekt diese Referenz auf das Objekt verwirft.
Eine Referenz auf ein Objekt geht auch bei Zuweisung eines anderen Objekts (bzw. null) verloren, z.B.
C#-Quelltext
1: 2: 3: 4: 5: 6:
| other_object.obj_ref = new Object();
Object o = new Object(); other_object.obj_ref = o; other_object.obj_ref = null; |
Yogu - Do 01.09.11 14:28
uwe1234 hat folgendes geschrieben : |
Durch welche Bedingungen verliert eine Instanz die Referenz, außer durch mein Beispiel? |
Eigentlich immer dann, wenn es garantiert ist, dass niemand mehr danach drauf zugreifen wird. Das kann auch schon vor dem Verlassen des Scopes passieren, und zwar, wenn innerhalb der Methode einfach nichts mehr mit dem Objekt gemacht wird:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| void test() { MyClass obj = new MyClass(); obj.DoSomething(); Console.WriteLine("Something done."); } |
Im Prinzip brauchst du dich darum überhaupt nichts zu kümmern, das macht alles das Framework.
uwe1234 - Do 01.09.11 21:48
Hallo zusammen,
danke für die Infos. Bin jetzt diesbezüglich etwas schlauer :)
Gruß
pdelvo - Sa 03.09.11 16:16
Oder wenn es nurnoch Referenzen über eine WeakReference gibt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!