constructors, garbage collec on, sta cs - computer science

44
Constructors, garbage collec0on, sta0cs CSCI 136: Fundamentals of Computer Science I • Keith Vertanen • Copyright © 2013

Upload: khangminh22

Post on 04-Apr-2023

0 views

Category:

Documents


0 download

TRANSCRIPT

Constructors,  garbage  collec0on,  sta0cs  

CSCI  136:  Fundamentals  of  Computer  Science  I    •    Keith  Vertanen    •    Copyright  ©  2013  

Overview  

2  

•  Where  Java  stores  stuff  – The  Heap  – The  Stack  – Breaking  both  –  Java  Garbage  Collector  (GC)  

•  CreaAng  objects  – Copy  constructors  – Methods  creaAng  new  objects  

•  StaAc  keyword  – StaAc  methods  and  instance  variables  

Stack  and  Heap  •  Stack  – 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  – When  you  call  a  method,  the  method  lands  on  top  of  a  call  stack  

– Stack  frame  •  Contains  the  state  of  the  method  • What  line  it  is  execuAng  •  Values  of  the  method's  local  variables  (including  parameters)  

– Method  stays  on  stack  unAl  it  finishes  execuAng  

4  

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

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

CompuAng  a  factorial  recursively  

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)        {              System.out.println("4!  =  "  +  fact(4));        }  }    

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    

CompuAng  a  factorial  recursively  

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)        {              System.out.println("4!  =  "  +  fact(4));        }  }    

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

Breaking  the  stack  

9  

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

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  

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

Where  things  live  •  Local  variables  live  on  the  stack  – Local  variables  in  a  method  – Parameters  passed  to  a  method  – Reference  variables  

•  Only  the  remote  control  lives  on  the  stack  

•  Objects  live  on  the  heap  – When  you  create  objects,  they  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  

11  

Heap  

Duck  myDuck  

myDuck  

The  miracle  of  object  creaAon  •  CreaAng  an  object  in  3  easy  steps:  

1)  Declare  a  reference  variable  2)  Create  an  object  

12  

Heap  

                           new  Duck();  

myDuck  

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  

13  

Heap  

Duck  myDuck  =  new  Duck();  

myDuck  

You  have  now  consumed  memory  on  the  heap  based  on  how  much  state  a  Duck  requires  to  be  stored  (i.e.  the  number  and  type  of  its  instance  variables).  

Java  Garbage  Collector  •  Java  tracks  #  of  variables  referring  to  an  object  – Once  no  one  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)  

14  

You're  so  going  to  have  to  this  yourself  in  data  structures.  

Killing  objects  •  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()  

dHeap  

Heap  

Killing  objects  •  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  

dHeap  

Killing  objects  •  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  

Killing  objects  •  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  

Killing  objects  •  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  

AEer  execuFng  line  06,  no  one  is  referring  to  the  first  Duck  object  anymore.    It  is  now  subject  to  garbage  collecFon.  

Killing  objects  •  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  

AEer  execuFng  line  08,  both  the  first  and  second  Ducks  objects  are  can  be  garbage  collected.  

Killing  objects  •  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  

dHeap  

Killing  objects  •  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

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

Breaking  the  heap  •  Memory  is  not  infinite  – You  can't  just  keep  new'ing  objects  forever  without  gefng  rid  of  any  

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  so  memory  is  never  freed  

Size  of  variables  in  Java  

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  references  variables  (Strings,  arrays,  Ducks,  etc.)  is  JVM  dependent.    But  there  is  always  overhead  for  objects!  

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  }  

AAer  execu0ng  line   #  Ducks  on  the  heap   Variable(s)  that  point  to  a  Duck  object  

04  

05  

08  

09  

10  

26  

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  }  

AAer  execu0ng  line   #  Ducks  on  the  heap   Variable(s)  that  point  to  a  Duck  object  

04   1   d  

05  

08  

09  

10  

27  

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  }  

AAer  execu0ng  line   #  Ducks  on  the  heap   Variable(s)  that  point  to  a  Duck  object  

04   1   d  

05   1   d  

08  

09  

10  

28  

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  }  

AAer  execu0ng  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  

10  

29  

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  }  

AAer  execu0ng  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  

30  

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  }  

AAer  execu0ng  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]  

Copy  constructors  •  Copy  constructor  – A  special  constructor  – Parameter  is  another  object  of  the  same  type  – Simply  copies  all  the  state  of  the  passed  in  object  

31  

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

A  copy  constructor!  

Methods  giving  birth  •  An  instance  method  can  create  a  new  object  and  return  it  

32  

public  Block  move(double  x,  double  y)  //  Create  a  new  block  based  on  this  block                                                                                //  but  at  a  new  (x,y)  position      public  Block  rotate()                                  //  Create  a  new  block  based  on  this  block                                                                                //  but  rotated  by  90  degrees  

Hey  rabbit,  what  do  you  know?    "My  locaAon  and  my  size!"    Hey  rabbit,  what  can  you  do?    "I  can  draw  myself  and  I  can  tell  if  somebody  clicks  on  me.    Ohh  and  um,  well  you  know,  I  can  make  them  there  baby  rabbits…"  

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

Rabbit  class,  part  1  

33  

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

Rabbit  class,  part  2  

34  

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  

35  

Math.java  

36  

Method  signature   Descrip0on  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  selecFon  of  the  staFc  methods  in  Math.java  

Math.java  

37  

 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  actually  create  an  object  of  type  Math.    

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

Using  Math  class  

38  

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.    Use  class  name  instead.  

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.  

Limits  of  staAc  methods  •  StaAc  methods  – Cannot  use  non-­‐staAc  instance  variables  

39  

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

Since  getWeight()  is  declared  staAc,  any  use  of  a  non-­‐staAc  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?

Limits  of  staAc  methods  •  StaAc  methods  – Cannot  call  non-­‐staAc  methods  

40  

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

StaAc  variables  •  StaAc  instance  variable  – One  variable  shared  among  all  instances  of  a  parAcular  class  

– Why?  •  Commonly  used  for  constants    

•  Eliminate  repeated  variables  that  are  always  the  same  –  Reduce  memory  needed  to  create  many  objects  of  same  type  

•  Track  a  single  value  related  to  a  class  type    –  e.g.  Number  of  objects  created  for  a  parAcular  class  

41  

public  static  final  double  PI  =  3.14159265358979323846;  

Reducing  memory  usage  

42  

public  class  Cow  {        private  String  name  =  "";        private  double  weight  =  0.0;            private  static  AudioFile  sound  =  new  AudioFile("cow.wav");          public  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.  

CounAng  created  objects  

43  

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  maoer  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  staAc  variables  can  be  declared  staAc  (but  don't  have  to  be).  

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  

44