3

I want to limit the no. of direct instance of a class( in Java) say to n, i.e. at any time, not more than n direct objects of the class exist in the memory. But there is no such limit on the no. of indirect objects, such as of any subclass of this class. Is there a way to achieve this in Java?

  • 5
    Curious to know the business case of such a requirement. – Vikdor Sep 23 '12 at 12:02
  • Yeah, very curious and concerned why you require this. Java isn't designed for this. Both methods I can think of that would allow you to count when an instance is released are both highly discouraged. – Dunes Sep 23 '12 at 12:13
  • I wonder if you could do this kind of thing by starting the jvisualvm with a special plugin that counts instances ... probably a stupid idea, but technical feasible? – Jens Schauder Sep 23 '12 at 12:26
  • You probably need some sort of a data structure such as lists rather than counting classes\sub-classes instances. – Muhammad Gelbana Sep 24 '12 at 11:31
  • @Dunes, What are the methods you thought of? – Yudhister Satija Jan 17 '17 at 11:17
  • @YudhisterSatija This was a long time ago. One of them was definitely using finalisers to count when an object was no longer referenced. That's a bad idea as it effects the performance of compacting GCs (the default). Compacting GCs don't actually know when an object becomes unreferenced. They just know that after GC, there exists an area of memory with no referenced objects that can be used for new objects. – Dunes Jan 18 '17 at 05:34
  • @YudhisterSatija The other reason finalisers are bad is that they are not executed deterministically. That is, you may have an unreferenced object stuck in the tenured generation. This means minor GCs (the majority) won't release the object and call it's finalise method. Rather, you will have to wait for a major GC for the object to have it's finalise method called. In which time you might have had multiple requests to create new instances, all of which will fail as you are unaware of the unreferenced instance. – Dunes Jan 18 '17 at 05:43

4 Answers4

4

Use Factory design pattern, throw exception if your instances exceed more than you limit.

http://www.oodesign.com/factory-pattern.html

below is a rough sample implementation.

public class AnyClass {
    private static final int limit_ = 8;
    private static int count = 0;

    private AnyClass() {}

    public static synchronized AnyClass getInstance() {
        if (count < limit_) {
            AnyClass anyClass = new AnyClass();
            count++;
            return anyClass;
        }
        return null;
    }
}
polaretto
  • 791
  • 9
  • 11
ManMohan Vyas
  • 4,004
  • 4
  • 27
  • 40
0

You can do:

static final AtomicInteger count = new AtomicInteger();

// in your parent constructor.
if (getClass() == Parent.class && count.incrementAndGet() >= LIMIT)
   throw new IllegalStateException();
Andriy Budzinskyy
  • 1,971
  • 22
  • 28
0

Java does not provide this possibility natively.

I think you could manage yourself the case with a pooled Factory or directly in the class constructor. In the constructor you check on a static counter INSTANCES (defined as a private numeric in your class) if INSTANCES > MAX_LIMIT then you throws an exception.

obe6
  • 1,743
  • 15
  • 23
0

I think doing this is a bad idea (not knowing your use case), but anyways...

You can count all the instances by putting some code in the constructor of that class. If ignoring instances of subclasses is needed, check the value returned by getClass().

To know when an instance is released, you can use weak references and a WeakHashMap to get an estimate of the number of instances still in use. The actual number of instances in use can be lower, because the garbage collection removes the instances at an unpredictable time. For an exact number you would need explicitly call some method when you know that an instance will no more be used.

Esko Luontola
  • 73,184
  • 17
  • 117
  • 128