The life and death of objects, sta2cs CSCI 136: Fundamentals of Computer Science II Keith Vertanen
Overview Where Java stores stuff The Heap The Stack Breaking both Java Garbage Collector (GC) CreaAng objects Copy constructors Methods creaang objects StaAc keyword StaAc methods and instance variables 2
Stack Stack vs. Heap Where method invocaaons live Where local variables live A chunk of memory Heap Where all objects live Another chunk of memory 3
The Stack Methods are stacked You call a method put on top of a call stack A method stays on stack unal it finishes execuang Each stack frame contains: What line it is execuang Values of all the method s local variables This includes parameters to the method 4
public void dostuff() boolean b = true; go(4); public void go(int x) int z = x + 24; crazy(); public void crazy() char c = 'a'; 5
public void dostuff() boolean b = true; go(4); public void go(int b) int c = b + 24; crazy(); public void crazy() char c = 'a'; 1 2 dostuff() boolean b true 3 What if we have variables in different methods that have the same name? crazy() char c 'a' go() int b 4 int c 28 go() int b 4 int c 28 dostuff() boolean b true 4 go() int b 4 int c 28 dostuff() boolean b true dostuff() boolean b true 6
CompuAng a factorial recursively public class Factorial public static long fact(long n) if (n <= 1) return 1; return n * fact(n - 1); public static void main(string [] args) long result = fact(4); System.out.println("4! = " + result); fact(1) n 1 fact(2) n 2 fact(3) n 3 0! = 1 1! = 1 2! = 1 x 2 = 2 3! = 1 x 2 x 3 = 6 4! = 4 x 3 x 2 x 1 = 24 Some example factorials. fact(4) n 4 main() 7
CompuAng a factorial recursively public class Factorial public static long fact(long n) if (n <= 1) return 1; return n * fact(n - 1); public static void main(string [] args) long result = fact(4); System.out.println("4! = " + result); 0! = 1 1! = 1 2! = 1 x 2 = 2 3! = 1 x 2 x 3 = 6 4! = 4 x 3 x 2 x 1 = 24 Some example factorials. fact(1) n 1 return 1 fact(2) n 2 return 2 * fact(1) fact(3) n 3 return 3 * fact(2) fact(4) n 4 return 4 * fact(3) main() fact(4) = 24 8
Breaking the stack fact(- 2) n - 2 public class Factorial Exception in thread "main" public static long fact(long java.lang.stackoverflowerror n) 0! = 1 1! = 1 2! = 1 x 2 = 2 3! = 1 x 2 x 3 = 6 4! = 4 x 3 x 2 x 1 = 24 Some example factorials. fact(- 1) n - 1 at Factorial.fact(Factorial.java:6) fact(0) at Factorial.fact(Factorial.java:6) n 0 at Factorial.fact(Factorial.java:6) return n * fact(n - 1); at Factorial.fact(Factorial.java:6) fact(1) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) n 1 public static void main(string at Factorial.fact(Factorial.java:6) [] args) at Factorial.fact(Factorial.java:6) long result = fact(4); fact(2) at Factorial.fact(Factorial.java:6) System.out.println("4! = " + result); n 2 at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) fact(3) at Factorial.fact(Factorial.java:6) n 3 at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) fact(4) at Factorial.fact(Factorial.java:6) n 4 at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6)... main() 9
Where things live Local variables live on the stack Local variables in a method Parameters passed to a method Reference variables e.g. passing in a int [] array, a Hero object, Only the remote control lives on the stack Objects live on the heap Objects instanaated with new, live on the heap Instance variables of an object Stored as part of the object living on the heap 10
The miracle of object creaaon CreaAng an object in 3 easy steps: 1) Declare a reference variable Heap myduck Duck myduck 11
The miracle of object creaaon CreaAng an object in 3 easy steps: 1) Declare a reference variable 2) Create an object Heap myduck new Duck(); 12
The miracle of object creaaon CreaAng an object in 3 easy steps: 1) Declare a reference variable 2) Create an object 3) Link the object and the reference You have now consumed memory on the heap based on how much state a Duck requires (i.e. the number and type of its instance variables). myduck Heap Duck myduck = new Duck(); 13
Java Garbage Collector Java tracks # of variables referring to an object As soon as nobody refers to an object, its memory can be freed Java's automaac Garbage Collector (GC) periodically handles this for you Exactly when is up to the JVM Enjoy it (while it lasts) You're so going to have to this yourself in data structures. 14
Object- killer #1 Reference goes out of scope permanently Killing objects public class DuckKiller1 public static void makeduck() Duck d = new Duck(); public static void main(string [] args) makeduck(); while (true) // Do something main() makeduck() main() main() d Heap Heap 15
Object- killer #1b Killing objects Variable inside curly braces goes out of scope 00 public class DuckKiller1b 01 02 public static void main(string [] args) 03 04 if (args.length >= 0) 05 06 Duck d = new Duck(); 07 08 while (true) 09 10 // Do something 11 12 13 main() line 04 line 05 line 06 d Heap 16
Object- killer #1b Reference goes out of scope permanently Killing objects 00 public class DuckKiller1b 01 02 public static void main(string [] args) 03 04 if (args.length >= 0) 05 06 Duck d = new Duck(); 07 08 while (true) 09 10 // Do something 11 12 13 main() line 04 line 05 line 06 line 07 line 08 Heap 17
Object- killer #2 Killing objects Assign the reference to another object 00 public class DuckKiller2 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 System.out.println("quack!"); 06 d = new Duck(); 07 System.out.println("quack!"); 08 d = new Duck(); 09 System.out.println("quack!"); 10 11 main() line 04 d Heap 18
Object- killer #2 Killing objects Assign the reference to another object 00 public class DuckKiller2 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 System.out.println("quack!"); 06 d = new Duck(); 07 System.out.println("quack!"); 08 d = new Duck(); 09 System.out.println("quack!"); 10 11 main() line 04 line 05 line 06 d Heap A@er execuang line 06, no one is referring to the first Duck object anymore. It is now subject to garbage collecaon. 19
Object- killer #2 Killing objects Assign the reference to another object 00 public class DuckKiller2 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 System.out.println("quack!"); 06 d = new Duck(); 07 System.out.println("quack!"); 08 d = new Duck(); 09 System.out.println("quack!"); 10 11 main() line 04 line 05 line 06 line 07 line 08 d Heap A@er execuang line 08, both the first and second Ducks objects can be garbage collected. 20
Object- killer #3 Killing objects Set the reference variable to null 00 public class DuckKiller3 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 System.out.println("quack!"); 06 d = null; 07 System.out.println("quack!"); 08 09 main() line 04 d Heap 21
Object- killer #3 Killing objects Set the reference variable to null 00 public class DuckKiller3 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 System.out.println("quack!"); 06 d = null; 07 System.out.println("quack!"); 08 09 main() line 04 line 05 line 06 d Heap A@er execuang line 06, no one is referring to the Duck object anymore. The Java garbage collector can now free up the Duck's memory. 22
Memory is not infinite Breaking the heap Can't keep new ing forever w/o gemng rid of any You can buy yourself some Ame: Increase memory with JVM flag: - Xmx<num>[k m g] import java.util.*; public class HeapDeath public static void main(string [] args) ArrayList<Duck> list = new ArrayList<Duck>(); while (true) Duck d = new Duck(); list.add(d); While variable d scopes out every loop, the Duck reference persists inside the ArrayList. Memory is never freed! 23
Size of variables in Java Type Memory size (bits, 8 bits = byte) byte 8 short 16 int 32 long 64 float 32 double 64 boolean not precisely defined char 16 hqp://righteousit.wordpress.com/tag/tcpip/ NOTE: The size of a reference variable s remote control is JVM dependent. But there is always overhead for the reference variable and for any instance variables inside the data type! 24
00 public class HeapPuzzler 01 02 public static void main(string [] args) 03 04 Duck d = new Duck(); 05 Duck [] a = new Duck[4]; 06 for (int i = 0; i < a.length; i++) 07 a[i] = new Duck(); 08 System.out.println("quack!"); 09 a[0] = null; 10 a[1] = d; 11 System.out.println("quack!"); 12 13 ABer execu2ng line # Ducks on the heap Variable(s) that point to a Duck object 04 1 d 05 1 d 08 5 d, a[0], a[1], a[2], a[3] 09 4 d, a[1], a[2], a[3] 10 3 (d, a[1]), a[2], a[3] Two variables that refer to the same Duck 25
Copy constructor Copy constructors A special constructor Parameter is another object of the same type Simply copies all the state of the passed in object public class Duck private String name = ""; private double weight = 0.0; A copy constructor! public Duck(Duck other) this.name = other.name; this.weight = other.weight; 26
Methods giving birth An instance method can create a new object and return it Hey rabbit, what do you know? My locaaon and my size! Hey rabbit, what can you do? I can draw myself. I can tell if somebody clicks on me. Ohh and um, well you know, I can make them there baby rabbits 27
Rabbit class, part 1 public class Rabbit private double x = 0.0; private double y = 0.0; private static final double size = 0.06; public Rabbit(double x, double y) this.x = x; this.y = y; public void draw() StdDraw.picture(x, y, "rabbit.png"); public boolean intersect(double x, double y) double deltax = (this.x - x); double deltay = (this.y - y); return (Math.sqrt(deltaX * deltax + deltay * deltay) < size);... 28
Rabbit class, part 2 public Rabbit breed() Rabbit baby = new Rabbit(this.x + (0.2 - Math.random() * 0.4), this.y + (0.2 - Math.random() * 0.4)); return baby; public static void main(string [] args) ArrayList<Rabbit> rabbits = new ArrayList<Rabbit>(); rabbits.add(new Rabbit(0.5, 0.5)); while (true) for (int i = rabbits.size() - 1; i >= 0; i- - ) Rabbit r = rabbits.get(i); r.draw(); if (r.intersect(stddraw.mousex(), StdDraw.mouseY())) rabbits.add(r.breed()); StdDraw.show(100); 29
StaAc vs. non- staac methods StaAc methods Forbidden from using instance vars of the class Non- staac methods (instance methods) Allowed to use instance vars A class can have: All staac methods e.g. Math class All non- staac methods A mix of both e.g. Wrapper classes like Double and Integer 30
Math.java Method signature public static int round(float a) Descrip2on Round to the nearest integer public static long round(double a) public static int min(int a, int b) Find the minimum of two numbers public static long min(long a, long b) public static float min(float a, float b) public static double min(double a, double b) public static int abs(int a) Return absolute value of a number public static long abs(long a) public static float abs(float a) public static double abs(double a) public static double random() Get a random number in [0.0, 1.0) public static double sqrt(double a) Take the square root of a number A selecaon of the staac methods in Math.java 31
Math.java public static final double E = 2.7182818284590452354; public static final double PI = 3.14159265358979323846; Constants in Math.java. /** * Don't let anyone instantiate this class. */ private Math() A private constructor. Makes it impossible to instanaate an object of type Math. All calls via staac method calls, e.g. Math.sqrt(), Math.min() The constructor of the Math class. 32
Using Math class int x = Math.round(42.2); int y = Math.min(56, 12); int z = Math.abs(- 343); These methods don't use instance variables, so there is no specific object to call the methods on. Methods called using class name. Math mathobj = new Math(); You can't do this since the constructor is private: Exception in thread "main" java.lang.error: Unresolved compilation problem: The constructor Math() is not visible There is no persistent state in the Math object, so no need to create an object on the heap. 33
StaAc methods Limits of staac methods Cannot use non- staac instance variables public class Cow private String name = ""; private double weight = 0.0; public static double getweight() return weight; Cow cow1 = new Cow(); Cow cow2 = new Cow(); System.out.println("weight = ", Cow.getWeight()); Since getweight() is declared staac, any use of a non- staac instance variable results in a compile error: The weight of which cow? Cow.java:8: non- static variable weight cannot be referenced from a static context return weight; ^ 34
StaAc methods Limits of staac methods Cannot call non- staac methods public class Cow private String name = ""; private double weight = 0.0; public double getweight() return weight; public static boolean isbig() return (getweight() > 500.0); Since isbig() is declared staac, any use of a non- staac instance method results in a compile error: Cow.java:13: non- static method getweight() cannot be referenced from a static context return (getweight() > 500.0); ^ 35
StaAc variables StaAc instance variable One var shared among all instances of a class Why? Commonly used for constants public static final double PI = 3.14159265358979323846; Eliminate repeated variables that are always the same Reduce memory, doesn t keep copies of idenacal objects Track a single value related to a class type e.g. Number of objects created for a paracular class 36
Reducing memory usage public class Cow private String name = ""; private double weight = 0.0; Normal instance variables, each Cow object has its own set of these variables. private static AudioFile sound = new AudioFile("cow.wav"); public void makenoise() sound.play(); All Cow objects share the same sound object. Only one AudioFile object is created on the heap, thus saving memory. 37
CounAng created objects public class Cow private String name = ""; private double weight = 0.0; private static int numcows = 0; Normal instance variables, each Cow object has its own set of these variables. public Cow() numcows++; public Cow(Cow othercow) this.name = othercow.name; this.weight = othercow.weight; numcows++; public static int getnumcows() return numcows; No maqer how many Cow objects we create, there is only ever one numcows instance variable that has a single value. Methods that only use staac variables can be declared staac (but don't have to be). 38
Summary How your data is stored Stack Heap Garbage collector CreaAng new objects Copy constructor Other methods creaang new object instances StaAc keyword For methods For instance variables Heap 39