3.2. Object’s life cycle

[2.4] Explain an Object’s Lifecycle (creation, “dereference by reassignment” and garbage collection)

The OCA Java SE 8 Programmer I exam will test your understanding of when an object is created, when it can be accessed, and when it can be dereferenced. The exam also tests your ability to determine the total number of objects that are accessible at a particular line of code. Primitives aren’t objects, so they’re not relevant in this section.

Unlike some other programming languages, such as C, Java doesn’t allow you to allocate or deallocate memory yourself when you create or destroy objects. Java manages the memory for allocating objects and reclaiming the memory occupied by unused objects.

The task of reclaiming unused memory is taken care of by Java’s garbage collector, which is a low-priority thread. It runs periodically and frees up space occupied by unused objects.

Java also provides a method called finalize, which is accessible to all the classes. The method finalize is defined in the class java.lang.Object, which is the base class of all Java classes. All Java classes can override the method finalize, which executes just before an object is garbage collected. In theory, you can use this method to free up resources being used by an object, although doing so isn’t recommended because its execution isn’t guaranteed to happen.

An object’s life cycle starts when it’s created and lasts until it goes out of scope or is no longer referenced by a variable. When an object is accessible, it can be referenced by a variable and other classes can use it by calling its methods and accessing its variables. I’ll discuss these stages in detail in the following subsections.

3.2.1. An object is born

An object comes into the picture when you use the keyword operator new. You can initialize a reference variable with this object. Note the difference between declaring a variable and initializing it. The following is an example of a class Person and a class ObjectLifeCycle:

In the preceding code, no objects of class Person are created in the class ObjectLifeCycle; it declares only a variable of type Person. An object is created when a reference variable is initialized:

The difference in variable declaration and object creation is illustrated in figure 3.9, where you can compare a baby name to a reference variable and a real baby to an object. The left box in figure 3.9 represents variable declaration, because the baby hasn’t been born yet. The right box in figure 3.9 represents object creation.

Figure 3.9. The difference between declaring a reference variable and initializing a reference variable

Syntactically, an object comes into being by using the new operator. But the String class is an exceptional case here. String reference variables can also be initialized by using string literal values:

Note

Initializing a reference variable and an instance is not same. Initializing a reference variable might not always result in the creation of a new instance. In chapter 4, we’ll cover in detail how String literal values are pooled in a String pool by JVM. Although using the new operator always creates a new String object, using a String literal value to initialize a String reference variable might not always create a new String object.

What happens when you create a new object without assigning it to any reference variable? Let’s create a new object of class Person in class ObjectLifeCycle2 without assigning it to any reference variable (modifications in bold):

In the preceding example, an object of the class Person is created, but it can’t be accessed using any reference variable. Creating an object in this manner will execute the relevant constructors of the class.

Exam Tip

Watch out for a count of instances created in a given code—the ones that are eligible for garbage collection and the ones that aren’t.

In the next section, you’ll learn what happens after an object is created.

3.2.2. Object is accessible

Once an object is created, it can be accessed using its reference variable. It remains accessible until it goes out of scope or its reference variable is explicitly set to null. Also, if you reassign another object to an initialized reference variable, the previous object becomes inaccessible from that variable. You can access and use an object within other classes and methods.

Look at the following definition of the class Exam:

class Exam {
    String name;
    public void setName(String newName) {
        name = newName;
    }
}

The class ObjectLife1 declares a variable of type Exam, creates its object, calls its method, sets it to null, and then reinitializes it:

The preceding example creates two objects of the class Exam using the same reference variable myExam. Let’s walk through what’s happening in the example:

  • creates a reference variable myExam and initializes it with an object of class Exam.
  • calls method setName on the object referenced by the variable myExam.
  • assigns a value null to the reference variable myExam such that the object referenced by this variable is no longer accessible through myExam.
  • creates a new object of class Exam and assigns it to the reference variable myExam.
  • calls method setName on the second Exam object, created in method main.

When creates another object of class Exam and assigns it to the variable myExam, what happens to the first object created by ? Because the first object can no longer be accessed using any variable, it’s considered garbage by Java and deemed eligible to be sent to the garbage bin by Java’s garbage collector. As mentioned earlier, the garbage collector is a low-priority thread that reclaims the space used by unused or unreferenced objects in Java.

What happens when an object become inaccessible? You’ll find out in the next section.

3.2.3. Object is inaccessible

An object can become inaccessible if it goes out of scope or is dereferenced by reassignment.

Variable goes out of scope

An object can become inaccessible if it goes out of scope:

In the preceding code, the variable myExam1 is a local variable defined within the if block. Its scope starts from the line where it’s declared until the end of the if block, marked with a closing brace . After this closing brace, the object referred by the variable myExam1 is no longer accessible. It goes out of scope and is marked as eligible for garbage collection by Java’s garbage collector. Similarly, the object referred to by the variable myExam2 becomes inaccessible at the end of the else block, marked with a closing brace .

Exam Tip

When an object goes out of scope, it can no longer be referenced and is marked for garbage collection.

Dereferencing by reassignment

A variable that already refers to an instance can be assigned another instance. In this case, the earlier instance is dereferenced and becomes eligible for garbage collection. Let’s work with a modified version of a previous code example:

In the preceding code, an Exam instance is created and assigned to the variable myExam . At myExam is set to null before being assigned another Exam instance . The code at reassigns yet another Exam instance to myExam, without explicitly setting it to null. Again, the instance created at is dereferenced. After the execution of , two MyExam instances are dereferenced by reassignment and are eligible for garbage collection.

At , another variable, yourExam, is initialized using an Exam instance. At , the variable myExam is assigned to the variable yourExam. This dereferences the Exam instance, which was assigned to yourExam earlier.

Figure 3.10 shows how Exam instances are referred to by the variables myExam and yourExam. The Exam instances highlighted using gray boxes represent unreferenced objects.

Figure 3.10. Objects can be dereferenced by reassignment of variables.

Exam Tip

An instance is dereferenced by reassignment when a variable is either explicitly set to null or is assigned another instance or reference variable.

3.2.4. Garbage collection

In the OCA Java SE 8 Programmer I exam, you’re likely to answer questions on garbage collection for code that has multiple variable declarations and initializations. The exam may query you on the total number of objects that are eligible for garbage collection after a particular line of code.

Automatic memory management

The garbage collector is a low-priority thread that marks the objects eligible for garbage collection in the JVM and then clears the memory of these objects. It enables automatic memory management because programmers aren’t required to mark these instances themselves.

When is an object garbage collected?

You can determine only which objects are eligible to be garbage collected. You can never determine when a particular object will be garbage collected. A user can’t control or determine the execution of a garbage collector. It’s controlled by the JVM.

Exam Tip

Watch out for questions with wordings such as “which objects are sure to be collected during the next GC cycle,” for which the real answer can never be known.

Let’s revisit the dog and leash analogy I used in chapter 2 to define object reference variables. In figure 3.11, you can compare an object reference variable with a leash and an object with a dog. Review the following comparisons, which will help you to understand the life cycle of an object and garbage collection:

  • An uninitialized reference variable can be compared to a dog leash without a dog.
  • An initialized reference variable can be compared to a leashed dog.
  • An unreferenced object can be compared to an unleashed dog.
Figure 3.11. Comparing object reference variables and objects to dog leashes and leashed and unleashed dogs

You can compare Java’s garbage collector to animal control. The way animal control picks up untethered dogs is like the way Java’s garbage collector reclaims the memory used by unreferenced objects.

Using System.gc() or Runtime.getRuntime().gc()

As a programmer, you can’t start execution of Java’s garbage collector. You can only request it to be started by calling System.gc() or Runtime.getRuntime().gc(). But calling this method doesn’t guarantee when the garbage collector would start (the call can even be ignored by the JVM). Watch out for exam questions that query you on the number of instances that have been garbage collected after calling System.gc(). It won’t guarantee any count, at any line of code.

Garbage collecting referenced objects

The garbage collector can also reclaim memory from a group of referenced objects. This group of variables is referred to as an island of isolation.

An instance can be referred to by multiple variables. So when you assign null to one of these variables, the instances can still be referenced using other variable(s). But a group of instances with no external reference becomes eligible for garbage collection. Let’s work with an example:

In the preceding example, an Exam instance can refer to an object of its own type, using its field other. At and , two variables, php and java, are created and initialized using Exam instances. At , java is assigned to php.other. At , php is assigned to java.other. At , when php is set to null, the instance referred to by it isn’t eligible for garbage collection because it can still be referenced using java.other. At , when java is also set to null, both the objects referred to by java and php become eligible for garbage collection. As shown in figure 3.12, even though both these objects can be referred to by each other, they can no longer be referenced in the method main. They form an island of isolation. Java’s garbage collector can determine such groups of instances.

Figure 3.12. A group of instances with no external references forms an island of isolation, which is eligible for garbage collection.

Now that you’re familiar with an object’s life cycle, you can create methods that accept primitive data types and objects as method arguments; these methods return a value, which can be either a primitive data type or an object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.142.2