Autor Beitrag
uwe1234
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Mi 31.08.11 17:56 
Hallo zusammen,

ich habe eine einfache Frage.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 31.08.11 19:29 
user profile iconuwe1234 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 36
Erhaltene Danke: 6

Win 95, Win XP, Win 7 64-bit
C# (VS 2010, #Develop), Java (eclipse)
BeitragVerfasst: Mi 31.08.11 22:26 
Hallo,

nochmal zu deinen Fragen:

user profile iconuwe1234 hat folgendes geschrieben Zum zitierten Posting springen:
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:

ausblenden 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:

ausblenden 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

Gruß
stes

_________________
"Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann." Joseph Weizenbaum
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 31.08.11 22:49 
user profile iconstes hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 36
Erhaltene Danke: 6

Win 95, Win XP, Win 7 64-bit
C# (VS 2010, #Develop), Java (eclipse)
BeitragVerfasst: Mi 31.08.11 23:27 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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#.
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

_________________
"Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann." Joseph Weizenbaum
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 36
Erhaltene Danke: 6

Win 95, Win XP, Win 7 64-bit
C# (VS 2010, #Develop), Java (eclipse)
BeitragVerfasst: Mi 31.08.11 23:44 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
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 ^^

_________________
"Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann." Joseph Weizenbaum
uwe1234 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 178
Erhaltene Danke: 21



BeitragVerfasst: Do 01.09.11 10:05 
lokales objekt in methode--> nach verlassen der methode
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 01.09.11 10:37 
Zitat:
Durch welche Bedingungen verliert eine Instanz die Referenz, außer durch mein Beispiel?

Näherungsweise immer dann wenn der Scope in dem die Referenz definiert wurde zu Ende ist.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
other_object.obj_ref = new Object();

Object o = new Object();
other_object.obj_ref = o; // <- Referenz auf obiges anonymes Objekt wird verworfen

other_object.obj_ref = null// <- Referenz auf Objekt o wird verworfen
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Do 01.09.11 14:28 
user profile iconuwe1234 hat folgendes geschrieben Zum zitierten Posting springen:
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:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
void test() {
  MyClass obj = new MyClass();
  obj.DoSomething();
  // Ab hier wird obj nicht mehr benötigt, kann also entfernt werden
  Console.WriteLine("Something done.");
}

Im Prinzip brauchst du dich darum überhaupt nichts zu kümmern, das macht alles das Framework.
uwe1234 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: Do 01.09.11 21:48 
Hallo zusammen,

danke für die Infos. Bin jetzt diesbezüglich etwas schlauer :)

Gruß
pdelvo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 55
Erhaltene Danke: 11



BeitragVerfasst: Sa 03.09.11 16:16 
Oder wenn es nurnoch Referenzen über eine WeakReference gibt

Für diesen Beitrag haben gedankt: Yogu