0

I came across opinions that some classes ("heavy class") should not be repeatedly created and disposed of as it takes too of JVM's overhead/time/resources. While it is possible to imagine what is a heavy-class - I have never came across any definition of it.

Background:

  • repeatedly creating and disposing of SimpleDateFormat for converison of date was seen as a bad practice. SimpleDateFormat is not thread safe and I would not be in favour of synchronization of it in the web environment.

So:

  • is there a proper definition of "heavy class" ?

UPDATE

I do not think of any definition of a "heavy class". If you can come up with any definition - I am happy to upvote...

Meanwhile I created a test to find out how long it takes for a JVM to create and dispose of SimpleDateFormat objects. On my i7 box I got 390-400 thousands of objects created and disposed of (run with heap memory limit 64Mb, -Xms32m -Xmx64m):

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;

public class SdfTest {

    static AtomicLong created = new AtomicLong(0L);
    static AtomicLong disposed = new AtomicLong(0L);

    public static class SimpleDateFormat2 extends SimpleDateFormat {

        private static final long serialVersionUID = 1L;
        public SimpleDateFormat2() {
            created.incrementAndGet();
        }

        @Override
        protected void finalize() throws Throwable {
           disposed.incrementAndGet();
           super.finalize();
        }
    }

    public static void  main(String[] args) {

        Runtime rt = Runtime.getRuntime();
        System.out.format("Start: total mem: %d, freeMemory: %d, maxMemory: %d%n",
                rt.totalMemory(), rt.freeMemory(), rt.maxMemory());

        LocalDateTime start = LocalDateTime.now();
        for (int i = 0; i < 10_000_000; i++) {
            new SimpleDateFormat2();
        }
        System.gc();
        LocalDateTime stop = LocalDateTime.now();

        Long durationMs = Duration.between(start, stop).toMillis();
        System.out.println("Duration: " + durationMs + " miliseconds");
        System.out.println("Created " + created + " and disposed of: " + disposed + " objects.");

        System.out.println("Average time of creating + disposing time: " + 1000 *
                ( (double) disposed.get() / durationMs) + " objects per second." );
    }
}

Scored:

Start: total mem: 32505856, freeMemory: 31597048, maxMemory: 59768832
Duration: 25568 miliseconds Created 10000000 and disposed of: 10000000 objects
Average time of creating + disposing time: 391113.8923654568 objects per second.

Witold Kaczurba
  • 9,845
  • 3
  • 58
  • 67
  • You really should add some references to the discussion you are referring to. That term seems to be an informal way of saying "a class whose instance creation takes a long time". And as for `SimpleDateFormat` - you should move to `java.time` and its associated formatters. If you absolutely need a `SimpleDateFormat`, consider keeping it in a `ThreadLocal`. – RealSkeptic Apr 08 '19 at 09:23
  • @RealSkeptic - I cant use java.time in this project. I am happy to upvote on full answers. – Witold Kaczurba Apr 08 '19 at 09:28
  • 2
    But you won't get a full answer, because we don't know where you got that term, if it is really meant what I think it meant in that context. The proper answer to your question is probably Just "No, there isn't", which I'm sure you won't be happy about. – RealSkeptic Apr 08 '19 at 09:30
  • https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – luk2302 Apr 08 '19 at 10:20

1 Answers1

2

I don't think there is a real universally accepted definition for this rather vague term, so I'll give you my own: any class that shows up in a profiler (or with more manual measurements) as a significant performance issue.

I've seen the Calendar class taking 10% of the CPU resources for one use case, pooling it made a big difference. I've seen application servers with and without stateless session bean pooling enabled and the pool made a measurable difference. I've seen XML parsers where pooling the relevant classes made a big difference (18%). Those are good examples. That doesn't mean I always pool Calendar instances; I do it for applications where it makes a difference. The object itself is not necessarily always "heavy", but it can be in some situations for some applications.

So, in short, a "heavy class" is one that can be measured to have a significant impact and where pooling makes a difference. The classes that fit the bill will depend on your application and how they are used.

ewramner
  • 5,810
  • 2
  • 17
  • 33