How to know how many objects were instantiated?

Asked

Viewed 2,556 times

5

In a Java application, how do I know how many objects in a class were instantiated? This doubt came to me by reading the article mentioned in the link below. It follows the excerpt that led me to doubt:

2.4 - Connection Factory

At some point in our application, we would like to have the control over the construction of the objects of our class. Much can be done through the constructor, how to know how many objects were instantiated or log on these instantiations.

Source: Caelum

  • 1

    I don’t know if this is exactly what you’re looking for, so I’ll leave it as a comment: To count the amount of instantiated objects you can use a static variable (e. g., static int instantiationCounter or static AtomicInteger instantiationCounter ) and increment the value every time the constructor is called. By default factory you can do interesting things like store the amount of global instantiations vs the amount of local instantiations (variable in the scope of Factory), etc.

3 answers

7


You will create a static member in the class that will hold the instance counter.

In the constructor will increment this counter.

You just need to know how many were instantiated or need to know how many are instantiated? If you need the second one, you will have to decrease the counter when the object is destroyed or made available.

If it should be decremented in the destruction, it will probably be done in the method finalize(). If you need to do this when it is no longer used, the decrease should occur in the method dispose() or something similar that is called whenever it is made available. Or you can use the interface java.lang.AutoCloseable in the class and the use of the object must be done in such a way as to ensure that it is called, as is the case with the try with Resources.

Example:

public class teste {
    protected static int count = 0;
    public teste() {
        count++;
    }
    protected void finalize() throws Throwable {
        count--;
    } 
    public static int getInstanceCount() {
        return count;
    }
}

I put in the Github for future reference.

Obviously this is a simplistic implementation and it will have problems in environment multithreaded.

This operation is not atomic. You may have a thread reading the counter, let’s assume that the counter is worth 1. Then another thread also reads the counter that is still worth 1. The first thread makes increment and it is worth 2. The second thread does the same and it is worth 2. But if it used to be 1, then it had an instance, now two new instances were created by 2 threads simultaneous, totaling 2 instances, but the counter is valid 2. The same occurs in the decrease, counting less than should.

To solve this would have to create some form of locking, ensuring that the operation is atomic.

  • But why would this solution be a problem for multithread environment? @bigown

  • 1

    @Duds I edited...

  • thanks @bigown

2

In Java there is a modifier called static which makes the values/methods within the scope of the class, not the instance, so you can easily create a variable public static int contadorInstancias = 0; and increment it whenever the manufacturer is used.

You can get more information about static here: http://www.guj.com.br/articles/121

2

First of all you must understand that a Fábrica de Conexões is nothing more than a class that will perform the creation of the objects for you, so you can use the adopted strategy in almost 100% of the cases with the modifier static.

The STATIC modifier

This modifier serves for a method or property to be relative to CLASS and not to the instantiated OBJECT. Example: let’s say in a class ObjectFactory has the following structure

public class ObjectFactory {
    private static int counter;
    private static ObjectFactory instance;

    public static object createInstance(TargetEnum target) {
        // ... lógica para instanciar a classe alvo
        counter++; // <-- aumentar o contador de objetos criados (este aqui não separa por tipo de objeto)
        // retornar o objeto instanciado.
    }

    // Retorna a quantidade de objetos instanciados
    public static int getQuantidadeObjetosInstanciados() {
        return counter;
    }

    public static ObjectFactory getInstance() {
        if (instance == null)
            instance = new ObjectFactory();
        return instance;
    }
}

Following this idea above the class can accomplish two things. The first is that whenever you use the method getInstance it will always return the same object regardless of how many times you call.

ObjectFactory obj1 = ObjectFactory.getInstance();
ObjectFactory obj2 = ObjectFactory.getInstance();

// obj1 === obj2 - sempre irá resultar em true e alteração em um alterará o outro também

The second is using the getQuantidadeObjetosInstanciados that will always show the value of instantiated elements

// ObjectFactory counter = 0
TargetClass objAlvo = ObjectFactory.createInstance(TargetEnum.TargetClass);
int qtdInstances = ObjectFactory.getQuantidadeObjetosInstanciados();
// qtdInstances = 1
TargetClass objAlvo2 = ObjectFactory.createInstance(TargetEnum.TargetClass);
int qtdInstances = ObjectFactory.getQuantidadeObjetosInstanciados();  
// qtdInstances = 2

You can combine them and everything, but it’s important to remember that in finalize of class it would be good if you decrement the counter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.