objects, variables, memory

39
Michele Van Dyne MUS 204B [email protected] https://katie.mtech.edu/classes/csci136 10 – Objects, Variables, Memory

Upload: others

Post on 26-Dec-2021

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Objects, Variables, Memory

Michele Van Dyne MUS 204B [email protected] https://katie.mtech.edu/classes/csci136

10 – Objects, Variables, Memory

Page 2: Objects, Variables, Memory

Where Java stores stuff ◦ The Heap

◦ The Stack

◦ Breaking both

◦ Java Garbage Collector (GC)

Creating objects ◦ Copy constructors

◦ Methods creating objects

Static keyword ◦ Static methods and instance variables

Page 3: Objects, Variables, Memory

Stack ◦ Where method invocations live

◦ Where local variables live

◦ A chunk of memory

Heap ◦ Where all objects live

◦ Another chunk of memory

3

Page 4: Objects, Variables, Memory

Methods are “stacked” ◦ You call a method → put on top of a call stack

◦ A method stays on stack until it finishes executing

◦ Each stack frame contains:

What line it is executing

Values of all the method’s local variables

This includes parameters to the method

4

Page 5: Objects, Variables, Memory

5

public void doStuff() { boolean b = true; go(4); } public void go(int x) { int z = x + 24; crazy(); } public void crazy() { char c = 'a'; }

Page 6: Objects, Variables, Memory

6

public void doStuff() { boolean b = true; go(4); } public void go(int b) { int c = b + 24; crazy(); } public void crazy() { char c = 'a'; }

doStuff() boolean b → true

doStuff() boolean b → true

go() int b → 4 int c → 28

1 2

doStuff() boolean b → true

go() int b → 4 int c → 28

3

crazy() char c → 'a'

doStuff() boolean b → true

go() int b → 4 int c → 28

4

Page 7: Objects, Variables, Memory

7

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.

main()

fact(4) n → 4

fact(3) n → 3

fact(2) n → 2

fact(1) n → 1

Page 8: Objects, Variables, Memory

8

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); } }

main() fact(4) = 24

fact(4) n → 4 return 4 * fact(3)

fact(3) n → 3 return 3 * fact(2)

fact(2) n → 2 return 2 * fact(1)

fact(1) n → 1 return 1

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.

Page 9: Objects, Variables, Memory

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.

9

public class Factorial { public static long fact(long n) { return n * fact(n - 1); } public static void main(String [] args) { long result = fact(4); System.out.println("4! = " + result); } }

main()

fact(4) n → 4

fact(3) n → 3

fact(2) n → 2

fact(1) n → 1

fact(0) n → 0

fact(-1) n → -1

fact(-2) n → -2

Exception in thread "main" java.lang.StackOverflowError at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) at Factorial.fact(Factorial.java:6) ...

Page 10: Objects, Variables, Memory

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 instantiated with new, live on the heap

◦ Instance variables of an object

Stored as part of the object living on the heap

10

Page 11: Objects, Variables, Memory

Creating an object in 3 easy steps: 1) Declare a reference variable

11

Heap

Duck myDuck

myDuck

Page 12: Objects, Variables, Memory

Creating an object in 3 easy steps: 1) Declare a reference variable

2) Create an object

12

Heap

new Duck();

myDuck

Page 13: Objects, Variables, Memory

Creating an object in 3 easy steps: 1) Declare a reference variable

2) Create an object

3) Link the object and the reference

13

Heap

Duck myDuck = new Duck();

myDuck

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).

Page 14: Objects, Variables, Memory

Java tracks # of variables referring to an object ◦ As soon as nobody refers to an object, its memory

can be freed ◦ Java's automatic Garbage Collector (GC) periodically

handles this for you Exactly when is up to the JVM

Enjoy it (while it lasts)

14

You're so going to have to this

yourself in data structures.

Page 15: Objects, Variables, Memory

Object-killer #1 ◦ Reference goes out of scope

permanently

15

public class DuckKiller1 { public static void makeDuck() { Duck d = new Duck(); } public static void main(String [] args) { makeDuck(); while (true) { // Do something } } }

main()

main()

makeDuck()

main()

d

Heap

Heap

Page 16: Objects, Variables, Memory

Object-killer #1b ◦ Variable inside curly braces

goes out of scope

16

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

Page 17: Objects, Variables, Memory

Object-killer #1b ◦ Reference goes out of scope

permanently

17

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

Page 18: Objects, Variables, Memory

Object-killer #2 ◦ Assign the reference to another object

18

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 }

d

Heap

main() line 04

Page 19: Objects, Variables, Memory

Object-killer #2 ◦ Assign the reference to another object

19

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 }

Heap

d

main() line 04 line 05 line 06

After executing line 06, no one is referring to the first Duck object anymore. It is now subject to garbage collection.

Page 20: Objects, Variables, Memory

Object-killer #2 ◦ Assign the reference to another object

20

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 }

Heap

d

main() line 04 line 05 line 06 line 07 line 08

After executing line 08, both the first and second Ducks objects can be garbage collected.

Page 21: Objects, Variables, Memory

Object-killer #3 ◦ Set the reference variable to null

21

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

Page 22: Objects, Variables, Memory

Object-killer #3 ◦ Set the reference variable to null

22

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 }

Heap

main() line 04 line 05 line 06

d

After executing line 06, no one is referring to the Duck object anymore. The Java garbage collector can now free up the Duck's memory.

Page 23: Objects, Variables, Memory

Memory is not infinite ◦ Can't keep new’ing forever w/o getting rid of any ◦ You can buy yourself some time:

Increase memory with JVM flag: -Xmx<num>[k|m|g]

23

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!

Page 24: Objects, Variables, Memory

24

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

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!

http://righteousit.wordpress.com/tag/tcpip/

Page 25: Objects, Variables, Memory

25

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 }

After executing line # Ducks on the heap

Variable(s) that point to a Duck object

04

05

08

09

10

1 d

1 d

5 d, a[0], a[1], a[2], a[3]

4 d, a[1], a[2], a[3]

3 (d, a[1]), a[2], a[3]

Two variables that refer to the same Duck

Page 26: Objects, Variables, Memory

Copy constructor ◦ A special constructor

◦ Parameter is another object of the same type

◦ Simply copies all the state of the passed in object

26

public class Duck { private String name = ""; private double weight = 0.0; public Duck(Duck other) { this.name = other.name; this.weight = other.weight; } }

A copy constructor!

Page 27: Objects, Variables, Memory

An instance method can create a new object and return it

27

Hey rabbit, what do you know? “My location 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…”

Page 28: Objects, Variables, Memory

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

Page 29: Objects, Variables, Memory

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

Page 30: Objects, Variables, Memory

Static methods ◦ Forbidden from using instance vars of the class

Non-static methods (instance methods) ◦ Allowed to use instance vars

A class can have: ◦ All static methods

e.g. Math class

◦ All non-static methods

◦ A mix of both

e.g. Wrapper classes like Double and Integer

30

Page 31: Objects, Variables, Memory

31

Method signature Description

public static int round(float a) 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 selection of the static methods in Math.java

Page 32: Objects, Variables, Memory

32

public static final double E = 2.7182818284590452354; public static final double PI = 3.14159265358979323846;

/** * Don't let anyone instantiate this class. */ private Math() {}

Constants in Math.java.

The constructor of the Math class.

A private constructor. Makes it impossible to instantiate an object of type Math.

All calls via static method calls, e.g. Math.sqrt(), Math.min()

Page 33: Objects, Variables, Memory

33

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.

Page 34: Objects, Variables, Memory

Static methods ◦ Cannot use non-static instance variables

34

public class Cow { private String name = ""; private double weight = 0.0; public static double getWeight() { return weight; } }

Since getWeight() is declared static, any use of a non-static instance variable results in a compile error:

Cow.java:8: non-static variable weight cannot be referenced from a static context return weight; ^

Cow cow1 = new Cow(); Cow cow2 = new Cow(); System.out.println("weight = ", Cow.getWeight());

The weight of which cow?

Page 35: Objects, Variables, Memory

Static methods ◦ Cannot call non-static methods

35

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 static, any use of a non-static 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); ^

Page 36: Objects, Variables, Memory

Static instance variable ◦ One var shared among all instances of a class

◦ Why?

Commonly used for constants

Eliminate repeated variables that are always the same

Reduce memory, doesn’t keep copies of identical objects

Track a single value related to a class type

e.g. Number of objects created for a particular class

36

public static final double PI = 3.14159265358979323846;

Page 37: Objects, Variables, Memory

37

public class Cow { private String name = ""; private double weight = 0.0; private static AudioFile sound = new AudioFile("cow.wav"); public static void makeNoise() { sound.play(); } }

Normal instance variables, each Cow object has its own set of these variables.

All Cow objects share the same sound object. Only one AudioFile object is created on the heap, thus saving memory.

Page 38: Objects, Variables, Memory

38

public class Cow { private String name = ""; private double weight = 0.0; private static int numCows = 0; public Cow() { numCows++; } public Cow(Cow otherCow) { this.name = otherCow.name; this.weight = otherCow.weight; numCows++; } public static int getNumCows() { return numCows; } }

No matter how many Cow objects we create, there is only ever one numCows instance variable that has a single value.

Normal instance variables, each Cow object has its own set of these variables.

Methods that only use static variables can be declared static (but don't have to be).

Page 39: Objects, Variables, Memory

How your data is stored ◦ Stack

◦ Heap

◦ Garbage collector

Creating new objects ◦ Copy constructor

◦ Other methods creating new object instances

Static keyword ◦ For methods

◦ For instance variables

Heap