I wanted to check if anyone can help me with some theory pointers & also some tools which can help me quantify costs.
I understand that some Objects might be "expensive" to create. For example - JAXBContext. So its preferred to make it as a singleton to maintain only one instance.
But, I wanted to understand what does it mean when the javadocs say that an object is "expensive" to create - does expensive mean, more CPU utilization, more time to create an object & why does it take more time compared to other java object creations.
I would appreciate if someone can help me with the following 2 things.
1. Articles/links to an in-depth explanation of what "expensive" means; preferably explanations at a byte-code level
2. Any tools that I can use to write a stand-along java program & quantify the costs.
Expensive generally means that the class will take a significant amount of resources. The cost of the creating the object depends on the object, and you need to take a deeper dive into the inner workings of the object to understand what's going on. Some objects might use lot of memory, some objects might need a lot of CPU processing to be created, and some objects might require IO on initialization.
In case of JAX, initialization of JAXBCOntext requires a lot of reflection which is a CPU intensive operation. The time required to load depends on the number of classes being reflected upon
Jayesh has covered the topic very well, I think, and I don't have anything to add to what he wrote.
Notice, though, that byte-code wasn't mentioned at all. That's because byte-code really has very little to do with "expense", except obviously that more byte-code is more expensive to execute. And you asked about "quantifying" costs... Well, first you have to identify the type of cost. That would be the "resources" which Jayesh mentioned. And to quantify that, the way to do it is generally to measure it by running sample code and see how much of those resources were used up. Usually you can't quantify by just looking at the code. It's true that you can review algorithms to see whether they are O(1) or O(n) or whatever, but that sort of thing is unlikely to figure into the code which creates an object.
Joined: Aug 12, 2002
Thanks Paul & Jayesh for the explanation. Both of your explanations were very clear. I am looking at some concrete steps on how I can measure this.
We need to run a sample code to see how much "resources" have been consumed. So, if I take creation of JAXB context example again, here are the steps I was thinking I could do to get some numbers.
1. Run the java program with a single thread to create the context. Single thread might not have significant variations. So, it might have to be multiple concurrent requests.
2. Monitor the CPU usage (the JAXB context example should give me higher than normal CPU usage because of reflection)
3. Get a heap-dump (using WAS) & profile it to see the heap dump usage (in the JAXB example I do not expect the heap dump usage to be abnormal.
4. capture the program response time (assuming this will be higher)
The above 4 steps should give me some basic info. Are there any other steps or checks to do to see if the operation is really expensive or not? For now, I am not considering any I/O or DB operations.
Anurag Swaym wrote:The above 4 steps should give me some basic info. Are there any other steps or checks to do to see if the operation is really expensive or not? For now, I am not considering any I/O or DB operations.
Well, first off, you're likely to need to run it many times. Don't forget that when we're talking about 'expensive' in computer terms, we may be talking about something that takes 1/10th or 1/100th of a second, as opposed to nanoseconds. When I'm timing things, I usually average them over at least 10,000,000 invocations - mind you, I'm usually testing pretty low-level stuff. But I'd certainly pick a figure that takes several seconds (and possibly even minutes) to run; and that will probably take some trial and error.
Also, your check doesn't appear to include monitoring other possibly limited resources, such as device handles; although you'd probably need to do this outside Java.
Finally, testing in single-threaded mode may give you some idea of what's happening, but it fairly obviously won't give you any indications of what happens under load; and that's often where 'bottlenecks' occur.
Isn't it funny how there's always time and money enough to do it WRONG?
To add to Winston's point, for objects that use a lot of memory, there is an added cost of the GC collecting the object from the heap. Since, GC runs in the background, the cost of GC won't be evident if you just create the object once in your test app. GC may not be even triggered if you run it only once. To get the true cost, you need to at least create as many objects to fill your heap, and then some. This will ensure that the GC pause/overhead is taken into account in your benchmarks.