Java: Find out memory size of object? [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
In Java, what is the best way to determine the size of an object?
In Actionscript I can usually just do:
var myVar:uint = 5;
getSize(myVar)
//outputs 4 bytes
How do I do this in Java?

If you turn off -XX:-UseTLAB you can check the Runtime.freeMemory() before and after. However in the case of local variables, they don't take space on the heap (as they use the stack) and you can't get it size.
However, an int is a 32-bit sign value and you can expect it will use 4-bytes (or more depending on the JVM and the stack alignment etc)
The sizeof in C++ is useful for pointer arithmetic. Since Java doesn't allow this, its isn't useful and possibly deliberately hidden to avoid developers worrying about low level details.

The only reason C had a sizeOf intrinsic (function? well something) was because they needed it for manual memory management and some pointer arithmetic stuff.
There's no need to have that in Java. Also how much memory an object takes up is completely implementation defined and can't be answered reliably, but you can try some statistics by allocating lots of the same object and averaging - this can work nicely if you observe some basic principles, but that's boring.
If we know some basics about our VM we can also just count memory, so for Hotspot:
2 words overhead per object
every object is 8byte aligned (i.e. you have to round up to the next multiple of 8)
at least 1 word for variables, i.e. even if you have an object without any variables we "waste" 1 word
Also you should know your language spec a bit, so that you understand why an inner class has 1 additional reference than is obvious and why a static inner class does not.
A bit of work, but then it's generally a rather useless thing to know - if you're that worried about memory, you shouldn't be using neither ActionScript nor Java but C/C++ - you may get identical performance in Java, but you'll generally use about a factor of 2 more memory while doing so...

I believe there is no direct way of doing this. #Peter Lawrey 's suggestion could be a close approximation. But, you cannot rely on calculating the object size by taking the difference between the available free memory before and after the Object buildup, as there could be lots of other allocations in background happening from other threads as well. Also, there could be a possibility that the garbage collector could fire up and free up some memory in between your opertions. Also specially, in a multithreaded environment relying in the memory difference is definitely not a solution.

Related

Dynamic memory allocation across programming languages

I have a question regarding dynamic memory allocation.
When it comes to C, memory is allocated using the functions malloc(), calloc() and realloc() and de-allocated using free().
However in objected oriented languages like C++,C# and Java, memory is dynamically allocated using the new and deallocated using delete keywords (operators) in case of C++.
My question is, why are there operators instead of functions for these objected oriented languages for dynamic memory allocation? Even when using new, finally a pointer is returned to the class object reference during allocation, just like a function.
Is this done only to simplify the syntax? Or is there a more profound reason?
In C, the memory allocation functions are just that. They allocate memory. Nothing else. And you have to remember to release that memory when done.
In the OO languages (C++, C#, Java, ...), a new operator will allocate memory, but it will also call the object constructor, which is a special method for initializing the object.
As you can see, that is semantically a totally different thing. The new operator is not just simpler syntax, it's actually different from plain memory allocation.
In C++, you still have to remember to release that memory when done.
In C# and Java, that will be handled for you by the Garbage Collector.
I believe it's done solely to simplify the syntax as you've said.
Operators are simply another way to call methods (or functions).
using "12 + 13" is no different than using Add(12, 13).
A way to see this is via the operator overrides in C# for example:
// Sample from - https://msdn.microsoft.com/en-us/library/8edha89s.aspx
public static Complex operator +(Complex c1, Complex c2)
{
Return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
It's a regular method but allows the usage of operators over complex classes.
I'm using the Add operator as an example since I see it as no different than the memory allocation operators such as "new".
The whole point of Object Oriented design/programming is to provide meaningful abstractions.
When you are doing good OO design; you do not think (immediately) on areas in memory. One thinks about of objects; that carry state and provide behavior.
Even when writing code in C++, in most cases, I don't have to worry about subtleties like "why will my bits be aligned", "how much memory does one of my objects required at runtime" and so on. Of course, these questions are relevant in certain situations; but within OO design; the true value comes from creating useful abstractions that help to solve "whatever domain" problems as precise, easy, maintainable, ... as possible.
For the "keyword" versus "function" thing: just have a look at Java. The fathers of the language simply didn't want Java programmers start thinking about "memory pointers". You only deal with objects; and references to objects. Thus, the concept of "allocating" memory, and getting back a "pointer" simply does not exist at all here. So, how would you then provide this functionality as library method?! Well, if you would like to: you can't.
Finally, to a certain degree, this is a matter of "taste/style" by the people designing the language. Sometimes people prefer a small language core; and do everything in libraries; and other people prefer to have "more" things built-in.
The new keyword is ideed to simplify the syntax, which is pretty suggestive and also does more than memory allocation, it invokes the constructor(s) also.
One thing you have said:
C++,C# and Java, memory is dynamically allocated and de-allocated using the new and delete keywords (operators)
for Java and C# it is only the new keyword, there is no delete. I know that in C# you are able to use using blocks to ensure that the resource will be released when the object is not used anymore, but this does not involves memory deallocation in every case, such as it's calling the Dispose method.
One more thing which needs to be pointed is that the goal of an object oriented programming language, as GhostCat just said, is to release the programmer to think of how memory is allocated in most of the cases, and more important, how are the objects released, this is why garbage collector was introduced.
The main principle is that as the programming language is higher, it has to abstract such things as memory management, and provide easy ways to solve the actual business problems one is looking for. Of course this might been considered when a programming langage is chosed for a specific task.
C :malloc calloc are basically the only ways in C to allocate memory.
malloc : it allocate uninitialized memory according to requested size without initializing it to any value
calloc : almost same as malloc ,plus it also initialize it to zero(0).
In both cases , you required something :
The requested memory size for allocation should be given at the time of initialization and it can be increase with realloc.
The allocated memory need to be deleted with free ,sometimes it can be result in a OOM error if somebody don't have a good memory to free the allocated memory although free is quite handy when you are doing lot of memory extensive work.
NOTE : Casting and size(to allocate memory) is required with malloc and calloc
C++: C++ also has malloc and calloc (free and reallocate too) along new and delete ,new and delete can think of as a modern way to allocate and free memory but not all of the OOP's based language have both. e.g java don't have delete.
new uses constructors to initialize default value so it's pretty useful while working with objects when you have various scenarios to set initial value using parameterize ,default or copy constructors.
NOTE : With new you don't have to do the appropriate casing unlike with malloc and calloc and no need to give a memory size for allocation. one less thing , right.
delete is used to release the memory, the delete call on some object also calls destructor which is the last place of the life-cycle of that object where you can do some farewell tasks like saving current state etc and then memory will be released .
Note : In C# and java the deallocation of memory is handled by Garbage-Collector who does the memory management to release the memory.It used various algos like mark-sweep to release the memory if there is no reference variable pointing to that memory or the reference variable value is set as null.
This may also lead to memory leak if there is a reference variable pointing to that object in memory which is no longer required.
The downside of GC is, this makes things slow

Why Java doesn't allow object on stack? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am taking some classes and object lessons in Java having C++ background. I want to know the reason why we cannot choose the objects to be declared on the stack memory? Why must everything go on the heap except for the primitive types?
Here's something to clarify what I was asking.
Essentially, if we have:
Scanner input = new Scanner(System.in);
Then why cannot we have it on stack in the first place?
One of the strongest attractors of the original Java design (in mid-1990s) was simplicity. Supporting heap-based objects is essential, whereas stack-based ones are an optimization. Java is not alone here: many languages take that approach (LISP, Haskell, JavaScript, Ruby, etc.). Stack-based allocation does happen in Java, but only as an internal optimization trick and not something that the user can control.
Especially keep in mind that there is an essential difference in how a pointer to an object passed to a function ("a reference passed to a method" in Java-speak) can be treated by the callee: it is not allowed to retain the pointer if it's stack-based. This alone creates huge complications and bug opportunities.
Finally, stack-based objects bring much less to a garbage-collected language than to manually-managed languages like C and C++.
The data on the stack, say a C struct, disappears after the function call has returned. Hence one would need copying and correction of pointers.
Think of the hidden extra functionality needed here:
struct S* f() {
struct S s = ...;
g(&s);
return &s;
}
Java was meant as simplification, having its own management of memory, and doing things immediately on the heap seemed more direct, less convoluted.
This in view of C++, with its copy constructors, pointers and aliases.
Java does not allow explicit on stack allocation of objects. The language is not competing with low level languages such as C, and the creators of the language made this choice as a simplification.
However times change, and Java has grown since its humble beginnings. As the JVM becomes more sophisticated, automatic allocation of objects to the stack has become possible. The rationale for this is similar to the 'register' keyword in C; let the compiler manage the low level detail. It has become better at doing it than humans. In Java automatic allocation of objects onto the stack has been hampered by two factors, firstly the Sun/Oracle JVM is very old and very complex now. It is difficult to change, and Oracle has been careful about preventing backwards breaks. Secondly, so far their work on stack allocations has not yielded the large benefits that were expected. It did improve some situations, but the JVM has its own trade offs and behaviours. So this comes down to a question of time/pay-off and priorities. I believe that work to improve the benefits of automatic allocation continues behind the scenes; but there are no plans to make it explicit.
To put it simple, the key advantage of objects on stack is that the memory is automatically managed for you. When function puts objects on stack, they are cleaned from memory on function exit.
Since java already has automated garbage collection, this key advantage doesn't bring that much.
Sure there is a speed of access performance price that you might pay by being unable to allocate objects on stack directly, but as Marko mentioned, there are internal optimizations that might do just that.
Why must everything go on the heap except for the primitive types?
This statement is not accurate. Primitive types can go on the heap as well if they are part of a class instance. A local variable is stored on the stack, where as class variables are on the heap.
As for why objects are stored on the heap. It's after all a design decision. One reason is that it is a managed area in the JVM that is subject to garbage collection. As a managed area in the JVM, it may be organized in generations and may grow or shrink in size. See this section from the JVM specification:
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated.

C++: would universal use of shared_ptr<> be equivalent to a gc?

This is just an academic question (I would never do this in real code):
If I were to use shared_ptr<> universally in my code, would the behavior be equivalent to a gc-collected language like Java?
If not, how would the behavior be different from a gc-embedded language? Which C++ construct would yield equivalent behavior compared to a gc-embedded language?
Note: In real coding, I strongly prefer the use of RAII and strict ownership over the use of any smart pointers. I also know that other less-generic pointers, unique_ptr<> would be more efficient. This question is just a query into smart-pointer equivalence.
No, there'd be a couple of important differences:
You would get a memory leak any time you have a cyclic reference. A garbage collector can handle cycles, ref-counting can't.
You would avoid any stalls or pauses because no garbage collection ever occurs. On the other hand, you'd likely spend more total CPU time cleaning up resources, because the amortized cost of an occasional garbage collection is pretty low, and ref-counting can be relatively expensive if you do it on everything.
Obviously the first point is the killer. If you did this, many of your resources wouldn't get freed, and you'd leak memory and your app just wouldn't behave very well.
Which C++ construct would yield equivalent behavior compared to a gc-embedded language?
None. C++ doesn't have a garbage collector because there's no way to implement a correct, reliable one. (Yes, I'm aware of Boehm's GC, and it's a good approximation, but it's conservative, and doesn't detect all references, only the ones it can be 100% sure of. There is no way, in a general C++ program, to implement a garbage collector that Just Works(tm))
#jalf says this in his answer:
You would avoid any stalls or pauses because no garbage collection ever occurs.
While smart pointers (or any reference counting scheme) have no pause while garbage collection occurs, you can get a pause if you null the last external pointer to a large data structure, and trigger a cascade of reference count adjustments and finalizations for each node in the data structure. While a smart smart-pointer implementation could ameliorate this, you'd be sacrificing immediate reclamation ... which some people claim is an advantage of smart pointers.
Also, there is an overhead of a few instructions each time you assign to a smart pointer-typed variable, and the overheads of allocating an object is greater.
Garbage collection happens whenever the GC decides that it should. shared_ptrs are not collected. An object managed by a shared_ptr will only ever be destroyed in the destructor of a shared_ptr. And therefore, you know exactly when memory can and can not be freed.
You still have control over when memory goes away with shared_ptr. You don't have that with a garbage collector (outside of coarse-grained commands like turning it on/off or modifying it's behavior a bit).
The main difference is that reference counting alone can't free circular data structures.
Many cases of such structures can nevertheless be handled by using weak_ptr appropriately, and some cases can be handled by delegating cleanup responsibility to a collection object.
However, the most frivolous spaghetti structures, if you want them (e.g. for math), can't have automated cleanup implemented by reference counting alone, because there will be circular sub-structures.
Cheers & hth.,
Its worth noting that a shared ptr is much larger that a Java reference. Generally this won't matter but some situations it might.
In Java 6, 64-bit JVMs still use 32-bit references access up to 32 GB of heap (it can do this because objects are on 8 byte boundaries) However a shared ptr uses two pointers (each 8 bytes in a 64-bit applications), the second pointer references an object which contains the counter. On libgcc it allocates 32-byte minimum to any malloc/new object. In total the shared pointer could be using 48 bytes which is relatively larger than 4 bytes. 44 bytes is not going to make a difference, but it could if you have lots of these.

How big is an Object? Why is there no sizeof? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
In Java, what is the best way to determine the size of an object?
sizeof java object
C has a sizeof operator, and it needs to have one, because the user has to manage calls to malloc, and because the size of primitive types (like long) is not standardized.
But in java cant we find the sizeof an object?
Also why java doesnot have sizeof operator or method?
You've kind of answered your own question, in c you manage memory in java the jvm does.
In c you're directly allocating the memory for the data structures you're storing (malloc) and so you often need to know the sizes of these things.
In java the memory system is largely abstracted away so you don't (usually) care you just call new and it'll do whatever it does and if different jvms do things differently the memory used by the classes you've declared may vary.
Sometimes it is useful to know how much memory your classes are taking up (say you're trying to reduce your memory footprint in a tightly constrained environment) but it's pretty rare that you'd need that sort of information at runtime.
Also why java doesnot have sizeof operator or method?
Answer #1 - because Java doesn't need this. In C, the sizeof operator is needed so that you can malloc objects of the right size, for doing certain kinds of pointer arithmetic, and so on. In Java, you don't need to (and can't) do those kinds of thing.
Answer #2 - the size of an object in Java is rather rubbery, and indeed can change through the lifetime of the object (at least, in some JVMs). Ergo, a sizeof operator would be problematic.
In c there is a lot of work with pointers. Programmer should manage memory by himself, so he should know the size of types. But in Java there is no manual memory management. JVM does all it, so no need in sizeof.
In C you have to manually manage memory usage, you stated as much in your question. Since you need to allocated space for an object and remove it, the sizeof operator is required to do this quickly and easily. In Java, memory management is taken care of by the JVM. You don't need to manually allocate and de-allocate memory so the sizeof operator isn't necessary.

array of structures, or structure of arrays?

Hmmm. I have a table which is an array of structures I need to store in Java. The naive don't-worry-about-memory approach says do this:
public class Record {
final private int field1;
final private int field2;
final private long field3;
/* constructor & accessors here */
}
List<Record> records = new ArrayList<Record>();
If I end up using a large number (> 106 ) of records, where individual records are accessed occasionally, one at a time, how would I figure out how the preceding approach (an ArrayList) would compare with an optimized approach for storage costs:
public class OptimizedRecordStore {
final private int[] field1;
final private int[] field2;
final private long[] field3;
Record getRecord(int i) { return new Record(field1[i],field2[i],field3[i]); }
/* constructor and other accessors & methods */
}
edit:
assume the # of records is something that is changed infrequently or never
I'm probably not going to use the OptimizedRecordStore approach, but I want to understand the storage cost issue so I can make that decision with confidence.
obviously if I add/change the # of records in the OptimizedRecordStore approach above, I either have to replace the whole object with a new one, or remove the "final" keyword.
kd304 brings up a good point that was in the back of my mind. In other situations similar to this, I need column access on the records, e.g. if field1 and field2 are "time" and "position", and it's important for me to get those values as an array for use with MATLAB, so I can graph/analyze them efficiently.
The answers that give the general "optimise when you have to" is unhelpful in this case because , IMHO, programmers should always be aware of the performance in different in design choices when that choice leads to an order of magnitude performance penalty, particularly API writers.
The original question is quite valid and I would tend to agree that the second approach is better, given his particular situation. I've written image processing code where each pixel requires a data structure, a situation not too dissimilar to this, except I needed frequent random access to each pixel. The overhead of creating one object for each pixel was enormous.
The second version is much, much worse. Instead of resizing one array, you're resizing three arrays when you do an insert or delete. What's more, the second version will lead to the creation of many more temporary objects and it will do so on accesses. That could lead to a lot of garbage (from a GC point of view). Not good.
Generally speaking, you should worry about how you use the objects long before you think about performance. So you have a record with three fields or three arrays. Which one more accurately depicts what you're modeling? By this I mean, when you insert or delete an item, are you doing one of the three arrays or all three as a block?
I suspect it's the latter in which case the former makes far more sense.
If you're really concerned about insertion/deletion performance then perhaps a different data structure is appropriate, perhaps a SortedSet or a Map or SortedMap.
If you have millions of records, the second approach has several advantages:
Memory usage: the first approach uses more memory because a) every Java object in heap has a header (containing class id, lock state etc.); b) objects are aligned in memory; c) each reference to an object costs 4 bytes (on 64-bit JVMs with Compressed OOPs or 32-bit JVMs) or 8 bytes (64-bit JVMs without Compressed OOPs). See e. g. CompressedOops for more details. So the first approach takes about two times more memory (more precisely: according to my benchmark, an object with 16 bytes of payload + a reference to it took 28 bytes on 32-bit Java 7, 36 bytes on 64-bit Java 7 with compressed OOPs, and 40 bytes on 64-bit Java 7 w/o compressed OOPs).
Garbage collection: although the second approach seems to create many objects (one on each call of getRecord), it might not be so, as modern server JVMs (e. g. Oracle's Java 7) can apply escape analysis and stack allocation to avoid heap allocation of temporary objects in some cases; anyway, GCing short-lived objects is cheap. On the other hand, it is probably easier for the garbage collector if there are not millions of long-lived objects (as there are in the first approach) whose reachability to check (or at least, such objects may make your application need more careful tuning of GC generation sizes). Thus the second approach may be better for GC performance. However, to see whether it makes a difference in the real situation, one should make a benchmark oneself.
Serialization speed: the speed of (de)serializing a large array of primitives on disk is only limited by HDD speed; serializing many small objects is inevitably slower (especially if you use Java's default serialization).
Therefore I have used the second approach quite often for very large collections. But of course, if you have enough memory and don't care about serialization, the first approach is simpler.
How are you going to access the data? If the accesses over the fields are always coupled, then use the first option, if you are going to process the fields by its own, then the second option is better.
See this article in wikipedia: Parallel Array
A good example about when it's more convenient to have separate arrays could be simulations where the numerical data is packed together in the same array, and other attributes like name, colour, etc. that are accessed just for presentation of the data in other array.
I was curious so I actually ran a benchmark. If you don't re-create the object like you are[1], then SoA beats AoS by 5-100% depending on workload[2]. See my code here:
https://gist.github.com/twolfe18/8168262c5420c7a62d39
[1] I didn't add that because if you are concerned enough about speed to consider this refactor, it would be silly to do that.
[2] This also doesn't account for re-allocation, but again, this is often something you can either amortize away or know statically. This is a reasonable assumption for a pure-speed benchmark.
Notice that the second approach might have negative impact on caching behaviour. If you want to access a single record at a time, you'd better have that record not scattered all across the place.
Also, the only memory you win in the second approach, is (possibly) due to member alignment. (and having to allocate a separate object).
Otherwise, they have exactly the same memory use, asymptotically. The first option is much better due to locality, IMO
Whenever I have tried doing number crunching in Java, I have always had to revert to C-style coding (i.e. close to your option 2). It minimised the number of objects floating around in your system, as instead of 1,000,000 objects, you only have 3. I was able to do a bit of FFT analysis of real-time sound data using the C-style, and it was far too slow using objects.
I'd choose the first method (array of structures) unless you access the store relatively infrequently and are running into serious memory pressure issues.
First version basically stores the objects in their "natural" form (+1 BTW for using immutable records). This uses a little more memory because of the per-object overhead (probably around 8-16 bytes depending on your JVM) but is very good for accessing and returning objects in a convenient and human-understandable form in one simple step.
Second version uses less memory overall, but the allocation of a new object on every "get" is a pretty ugly solution that will not perform well if accesses are frequent.
Some other possibilities to consider:
An interesting "extreme" variant would be to take the second version but write your algorithms / access methods to interact with the underlying arrays directly. This is clearly going to result in complex inter-dependencies and some ugly code, but would probably give you the absolute best performance if you really needed it. It's quite common to use this approach for intensive graphics applications such as manipulating a large array of 3D coordinates.
A "hybrid" option would be to store the underlying data in a structure of arrays as in the second version, but cache the accessed objects in a HashMap so that you only generate the object the first time a particular index is accessed. Might make sense if only a small fraction of objects are ever likely to accessed, but all data is needed "just in case".
(Not a direct answer, but one that I think should be given)
From your comment,
"cletus -- I greatly respect your thoughts and opinions, but you gave me the high-level programming & software design viewpoint which is not what I'm looking for. I cannot learn to ignore optimization until I can get an intuitive sense for the cost of different implementation styles, and/or the ability to estimate those costs. – Jason S Jul 14 '09 at 14:27"
You should always ignore optimization until it presents itself as a problem. Most important is to have the system be usable by a developer (so they can make it usable by a user). There are very few times that you should concern yourself with optimization, in fact in ~20 years of professional coding I have cared about optimization a total of two times:
Writing a program that had its primary purpose to be faster than another product
Writing a smartphone app with the intention of reducing the amount of data sent between the client and server
In the first case I wrote some code, then ran it through a profiler, when I wanted to do something and I was not sure which approach was best (for speed/memory) I would code one way and see the result in the profiler, then code the other way and see the result. Then I would chose the faster of the two. This works and you learn a lot about low level decisions. I did not, however, allow it to impact the higher level classes.
In the second case, there was no programming involved, but I did the same basic thing of looking at the data being sent and figuring out how to reduce the number of messages being sent as well as the number of bytes being sent.
If your code is clear then it will be easier to speed up once you find out it is slow. As Cletus said in his answer, you are resizing one time -vs- three times... one time will be faster than three. From a higher point of view the one time is simpler to understand than the three times, thus it is more likely to be correct.
Personally I'd rather get the right answer slowly then the wrong answer quickly. Once I know how to get the right answer then I can find out where the system is slow and replace those parts of it with faster implementations.
Because you are making the int[] fields final, you are stuck with just the one initialization of the array and that is it. Thus, if you wanted 10^6 field1's, Java would need to separate that much memory for each of those int[], because you cannot reassign the size of those arrays. With an ArrayList, if you do not know the number of records beforehand and will be removing records potentially, you save a lot of space upfront and then later on as well when you go to remove records.
I would go for the ArrayList version too, so I don't need to worry about growing it. Do you need to have a column like access to values? What is your scenario behind your question?
Edit You could also use a common long[][] matrix.
I don't know how you pass the columns to Matlab, but I guess you don't gain much speed with a column based storage, more likely you loose speed in the java computation.

Categories