6.7 Übungen
6.7 Übungen
6.7.1 Referenzieren, Dereferenzieren und GCImplementieren Sie die Klasse Person mit folgenden Eigenschaften:
|
Hauptprogramm mit folgenden Eigenschaften:
|
Testen des Programms mit den Optionen -Xms -Xmx -Xlog:gc
Beispiel:
java -Xms64m -Xmx256m -Xlog:gc block7.gc.Main
Dies bewirkt das Starten einer Javaanwendung mit
- 64 Megabyte initialem Freispeicher (-Xms64m)
- 256 Megabyte maximalem Freispeicher (-Xmx256m)
- Protokollieren auftretender Garbagecollections (-Xlog:gc)
Allgemeine Überlegungen:
- Wie kann man erzwingen das die erste Person und Ihre Vorfahren zum Löschen freigegeben werden?
- Fügen die unten aufgeführte Kontrollmethode zum Auslesen der Speicherdaten an interessanten Stellen aus.
Tipp: Benutzen die folgende Beispielmethode zum Auslesen des Speicherverbrauchs.
Aufgaben
Variieren Sie den initialen, maximalen Speicher sowie die Anzahl der Generationen um
- Implizite GCs zu provozieren, zu vermeiden
- Eine OutOfMemory Ausnahme zu provozieren
- Erhöhen Sie Ihren Speicherverbrauch bis Sie an die Grenzen Ihres Systems kommen. Vorsicht! Nähern Sie sich Ihren Systemgrenzen in kleinen Schritten. Ihr System kann für eine gewisse Zeit durch Überlastung unbenutzbar werden!
Ein Testprogramm
Anbei ein einfaches Testprogramm welches eine Person ohne Vorfahren erzeugt und dann in einer Schleife neue Personen mit immer mehr Vorfahren erzeugt.
Die Konstante mit den Generationen kann bis zu einem Wert von etwa 20 erhöht werden.
package s1.block6; public class Test { /** * Zu erzeugende Generationen */ public static int generationen = 3; // Initial testen //public static int generationen = 19; // mit -Xlog:gc //public static int generationen = 22; // mit -Xmx500m -Xlog:gc //public static int generationen = 23; // mit -Xms500m -Xmx1024m -Xlog:gc public static void main(String[] args) { Person p; systemStatus(); for (int i=0; i<= generationen; i++) { System.out.println("*** Erzeuge " + i + " Generationen ***"); // Der alte Personenbaum wird implizit dereferenziert p = new Person(i); // Verlängern der Laufzeit. Dies erlaubt eine bessere Beobachtung mit jonsole // Der alte Vorfahrenbaum wird durch die Zuweisung dereferenziert //p = new Person(i); //p = new Person(i); systemStatus(); System.out.println("*** Ende. Erzeuge " + i + " Generationen ***"); } } public static void systemStatus(){ Runtime r = Runtime.getRuntime(); System.out.println("*** Systemstatus ***"); System.out.println("* Prozessoren : " + r.availableProcessors()); System.out.println("* Freier Speicher: " + r.freeMemory()); System.out.println("* Maximaler Speicher: " + r.maxMemory()); System.out.println("* Gesamter Speicher: " + r.totalMemory()); System.out.println("*** Ende Systemstatus ***"); } }
6.7.2 Tiefes Kopieren
Benutzen Sie den Quellcode der vorhergehenden Übung.
Schreiben Sie eine Klasse mir dem Namen Adresse und den folgenden Eigenschaften
- öffentliche Attribute ort, plz, strasse, hausnummer
- einen öffentlichen Konstruktor der alle Attribute erfasst
- einen "Copy Constructor" für die Klasse
Erweitern Sie die Klasse Person wie folgt:
- Attribut wohnort vom Typ Adresse
- "Copy Constructor" für die Klasse
Wenden Sie den "Copy Constructor" im Hauptprogramm an.
Optional
Schreiben Sie einen "Copy Constructor" der maximal n Generationen kopiert.
6.7.3 Tiefes Vergleichen
Erweitern Sie die Klassen aus den vorgehenden Beispielen wie folgt:
Klasse Person
- Fügen Sie einen Konstruktor hinzu der Name und alle vier Parameter für einen Geburtsort erfasst
- Implementieren eine equals() Methode die den Vergleich basierend auf Namen und den Inhalten des Geburtsort ausführt
Klasse Adresse
- Implementieren Sie eine equals() Methode die auf alle Attribute der Klasse prüft
Hauptprogramm
- Entwickeln Sie Testroutinen die die unterschiedlichen möglichen Fälle abprüfen
Tipp Die equals() Methode muss aus Typisierungsgründen ein Objekt vom Typ Object übernehmen. Mit dem unten aufgeführten Codestück kann man testen ob der EIngabeparameter vom gleichen Typ wie das aktuelle Objekt ist. Ist dies nicht der Fall so können die Objekte nicht gleich sein.
public boolean equals(Object obj) { ... if (this.getClass() == obj.getClass() )
6.7.4 "Walkthrough" Beispiel
Die hier gezeigte Übung wird interaktiv in der Vorlesung entwickelt. Die Arbeitsanweisungen sind im Quellcode enthalten.
Der Ausgangspunkt ist die Klasse Ware und die Klasse Lager die als Hauptprogramm dient:
Ziel ist es eine Lösung zu entwickeln in der die Klasse Ware mit einem Lager verwendet werden kann:
Klasse Ware
package s1.block6; /** * Dies ist die Dokumentation der Klasse Ware. Ware dient zum Verwalten von Gütern * mit Preisen und Namen in einem Lager. * @author Stefan Schneider * @version 1.1 * @see Lager */ public class Ware { /* * 7. Anlegen eine Copy Constructor * 7.1 Alle Werte des Objekts werden kopiert * 7.2 Es wird bei Bedarf eine neue Empfehlung angelegt */ /** * Der aktuelle Mehrwertsteuersatz 2010. * Er liegt zur Zeit bei {@value}. * @since 1.0 * @version 1.0 */ public static final double mws = 0.19; private double nettoPreis; //Deklaration public boolean halbeMws; private String name; public Ware empfehlung; /** * Konstruktor fuer die Klasse Ware * @param n der Name der Ware * @param np der Nettorpreis * @param hmws halber Mehrwertsteuersatz für Ware gueltig */ public Ware(String n, double np, boolean hmws) { name = n; nettoPreis = np; halbeMws = hmws; } /** * Liefert den Namen einer Ware zurueck. * @return Name der Ware */ public String get_name() { return name; } /** * Setzen eines neuen Nettopreis * @param npr der neue Nettopreis */ public void set_nettoPreis(double npr) { nettoPreis = npr; } /** * Ausdrucken aller Werte auf der Konsole */ public void drucken() { drucken(0); } /** * Ausdrucken aller Werte auf der Konsole mit vorgebener Einrueckung * für Empfehlungen * @param einruecken eingerueckte Stellen für Empfehlungen */ private void drucken(int einruecken) { String leerStellen = ""; for (int i = 0; i < einruecken; i++) { leerStellen = leerStellen + " "; } System.out.println(leerStellen + "Name: " + name); System.out.println(leerStellen + "netto: " + nettoPreis); System.out.println(leerStellen + "Brutto: " + bruttoPreis()); System.out.println(leerStellen + "Halbe Mws:" + halbeMws); if (empfehlung != null) { // Empfohlene Bücher werden eingerückt empfehlung.drucken(einruecken + 2); } } /** * Ausgabe des Nettopreis * @return der Nettopreis */ public double nettoPreis() { return nettoPreis; } /** * Ausgabe des Bruttopreis * @return der Bruttopreis */ public double bruttoPreis() { double bp; //temporaere Variable; keine Klassenvariable if (halbeMws) { bp = Math.round(nettoPreis * (mws / 2 + 1) * 100) / 100; } else { bp = Math.round(nettoPreis * (mws + 1) * 100) / 100; } return bp; } }
Klasse Lager
package s1.block6; /** * Die Klasse Lager verwaltet eine bestimmte Anzahl von Waren * @author s@scalingbits.com */ public class Lager { /* * Aufgaben * 1. Verwalten von n Waren in einem Feld * 1.1 Deklarieren eines privaten Feldes * 1.2 Zugriffsmethoden zum Setzen und Auslesen des Feldes * 2. Implementieren eines Konstruktors der das Lager * für n Waren initialisiert * 3. Methode zum Ausräumen des Lagers * 4. Erzeugung eines Singletons zum Erzeugen genau eines Lagers * 5. Anlegen einer neuen Klasse MainLager * 5.1 Umkopieren der main() Methode aus der Klasse Lager in die Klasse * MainLager.main() * 8. Testen des Copy Constructors * 8.1 Belegen Sie die ersten 500 Lagerpositionen mit Waren * 8.2 Klonen Sie die ersten 500 Lagerpositionen und belegen Sie die * folgenden 500 Lagerpositionen mit Ihnen * 8.3 Löschen Sie Ihr Lager indem Sie alle Postionen mit null belegen * 8.4 Implementieren Sie eine Schleife die einige Minuten läuft * und testen Sie den Speicherverbrauch mit jconsole oder */ public static void main(String[] args) { Ware ware1 = new Ware("Zeitung",12.12,true); System.out.println("Ware1 ohne Empfehlung:"); ware1.drucken(); double p = ware1.nettoPreis(); Ware ware2 = new Ware("Potter Bd1",31.12,false); Ware ersterBand = ware2; ware1.empfehlung= ware2; System.out.println("Ware1 mit Empfehlung:"); ware1.drucken(); // Erzeugen einer Ware mit 7 verketteten Empfehlungen Ware ware3; Ware hp1=ware2; for (int i=2; i<= 7; i++) { ware3 = new Ware("Potter Bd" + i,31.25+i,false); ware2.empfehlung = ware3; ware2 = ware3; } System.out.println("Alle Harry Potter Baende drucken"); hp1.drucken(); } }
Klasse MainLager
package s1.block6; /** * * Eine Hilfsklasse zur Implementierung eines Hauptprogramms * * @author sschneid * @version 1.0 */ public class MainLager { /* * 6. Testen der Klasse Main * 6.1 Aufruf des Singleton der Klasse Lager * 6.2 Einfügen zweier Waren * 6.3 Drucken zweier Waren */ public static void main(String[] args) { Ware ware1 = new Ware("Zeitung", 12.12, true); ware1.drucken(); double p = ware1.nettoPreis(); Ware ware2 = new Ware("Potter Band 1", 31.12, false); Ware ersterBand = ware2; Ware ware3; for (int i = 2; i <= 7; i++) { ware3 = new Ware("Potter Band" + i, 31.12, false); ware2.empfehlung = ware3; ware2 = ware3; } } }
- 6896 views