Implementation of the heap in the Java Memory Model - java

i was wondering what spcecifically the heap stores in its nodes? I understand a heap to be a kind of binary tree and from what I have studied of trees, the nodes contain a reference to the value stored. My question was in the case of the java heap, does the node structure contain a Java object reference to the location (stored somewhere else in RAM) of a stored object (the case a reference type), or a pointer to the memory location of the data type, or some other representation?
Reading about the subject I thought it strange that where an object is defined as a local variable, and is thus present both in the stack, as well as the heap (until I realized that this would be necissary since local variables are supposed to only be viziable to the relevent thread with the relevant thread stack) - however I still thought it odd to use a pair of object references like this and wondered perhaps whether I had misunderstood its implementation?

The Java heap just has to confirm to part 2.5.3 of the VM specification. There is no single implementation, so your question does not make sense strictly speaking.
There's too little space here to fully clarify the Oracle server and client VM. You should read into it for your target VM and ask more specific questions if you get stuck.
You should compare the java stack and heap to the related concepts (stack allocation vs. malloc) in C with the difference that you do not need to free them due to GC and are not allowed to do pointer arithmetics because objects can get moved at any time.
The java memory model on the other hand prescribes what guarantees the VM has to make under concurrent access to various types of variables. Compare to C++'s std::atomic. This is unrelated to the memory layout.

Related

How to avoid copying data between Java and Native C++ Code

I am writing C++ library that will be used by different Android applications to process some kind of data organized like two-dimensional storage where each dimension has no predefined restrictions for size (like array of arrays of float, and size of arrays can be quite large).
Current solution uses SWIG to copy data from memory allocated by Java code to C++ structures. It turns out that each array of float value (in Java) became vector of float (in C++).
The problem is that duplication of a large amount of data increases the risk of running out of memory available for application. I understand that, in any case, memory consumption issue should be resolved by input volume limitation, but the library does not know how much memory is available and should have whole data (access to any data element is needed repeatedly) to perform correct processing.
So now I am considering possibility to use one data storage for Java and C++, so C++ code require direct access to data stored by Java code to memory allocated on Java side (making memory allocated by C++ code as single storage is not considered).
I want to know how to organize such memory sharing in a safe manner (preferably using SWIG).
I feel that some difficulties can be with such implementation, e.g. with Java garbage collector (C++ code can address to storage which already deallocated) and slowing memory access through the wrapper (as mentioned earlier, the library requires repeated access to each data item)… but perhaps someone advise me a reliable solution.
The explanation of why my idea is wrong can be accepted, if supported with sufficiently and compelling arguments.
You can take access to raw array of data using Critical Native implementation. This tecknology allow to access directly to jvm memory without owerhead of transfering data between Java and native code.
But this have next restrictions:
must be static and not synchronized;
argument types must be primitive or primitive arrays;
implementation must not call JNI functions, i.e. it cannot allocate Java objects or throw exceptions;
should not run for a long time, since it will block GC while running.
The declaration of a critical native looks like a regular JNI method, except that:
it starts with JavaCritical_ instead of Java_;
it does not have extra JNIEnv* and jclass arguments;
Java arrays are passed in two arguments: the first is an array length, and the second is a pointer to raw array data. That is, no need to call GetArrayElements and friends, you can instantly use a direct array pointer.
Look at original answer and source article for details.

Java Memory Management

I have two questions with respect to Java memory management.
Where are static and instance variables stored? I believe static var are stored in premgen, but I am not sure about the instance var.
Is permgen a subset of heap or method area?
When I was googling, I found some stating that static vars are stored in the permgen section of heap, but others stating that permgen is a subset of the method area. If the later is true, then are the static variables stored in method area?
Where are static and instance variables stored?
It changes from Java version to Java version, runtime to runtime. eventually, Java is written to hide away memory details such as "Where do my objects sit in memory?".
Some compilers might optimize the objects away, declare them on the stack or any place they find suitable.
So the answer is - "We can't tell for sure, does it really matter for Java anyway?"
Stack or Heap storage depends more on whether the variable is primitive, e.g. int, or Objects.
Unless your primitive is part of an object, it will most likely be created on the call stack. Otherwise it will be created as part of the object on the heap.
And as others have mentioned, there is no more PermGen in stable Java ( i.e. 8 ) and moving forward.
PermGen elimination in JDK 8
Do Java primitives go on the Stack or the Heap?
Where does the JVM store primitive variables?
in JDK 8 there is no PERMGEN any more:
With the advent of JDK8, we no longer have the PermGen. No, the metadata information is not gone, just that the space where it was held is no longer contiguous to the Java heap. The metadata has now moved to native memory to an area known as the “Metaspace”.
check below link for details and for answering your 2nd question too.
http://www.infoq.com/articles/Java-PERMGEN-Removed

Java: How does the Array provide instant-lookup

More specifically, how does the Array object in Java allow users to access each bucket in constant time? I understand that Java allocates memory equivalent to the specified size at initialization, but what about the structure of it allows such rapid lookup? The reason I am asking is because it's something not available in any other data structure save those that use Array representations of data.
Another (possibly silly) question is why can't other data structures provide such quick lookup of the stored data? I guess this question can/will be answered by the answer to the first question (how Arrays are implemented).
An array is just stored as a big contiguous block of memory.
Accessing an element is a matter of:
Finding where the data starts
Validating the index
Multipying the index by the element size, and adding the result to the start location
Accessing that memory location
Note that this is all done in the JVM, not in byte code. If arrays didn't exist at a JVM level, you couldn't fake them up within pure Java. Aside from anything else, arrays are the only objects in Java which logically vary in size between instances within the same JVM. (It's possible that some JVMs have clever systems to use compressed references in some cases and not in others, but that's an implementation detail rather than a logical difference.)

trying to store java objects in contiguous memory

I am trying to implement a cache-like collection of objects. The purpose is to have fast access to these objects through locality in memory since I'll likely be reading multiple objects at a time. I currently just store objects in a java collections object like vector or deque. But I do not believe this makes use of contiguous memory.
I know this can be done in C, but can it be done in Java? These objects may be of varying lengths (since they may contain strings). Is there a way to allocate contiguous memory through Java? Is there a Java collections object that would?
Please let me know.
Thanks,
jbu
You can't force it. If you allocate all the objects in quick succession they're likely to be contiguous - but if you're storing them in a collection, there's no guarantee that the collection will be local to the actual values. (The collection will have references to the objects, rather than containing the objects themselves.)
In addition, GC compaction will move values around in memory.
Have you actually profiled your app and found this is a bottleneck? In most cases I'd expect other optimisations could help you in a more reliable way.
No, you can't guarantee this locality of reference.
By allocating a byte array, or using a mapped byte buffer from the nio packages, you could get a chunk of contiguous memory, from which you can decode the data you want (effectively deserializing the objects of interest from this chunk of memory). However, if you repeatedly access the same objects, the deserialization overhead would likely defeat the purpose.
Have you written this code yet in Java? And if so, have you profiled it? I would argue that you probably don't need to worry about the objects being in contiguous memory - the JVM is better at memory management than you are in a garbage collected environment.
If you're really concerned about performance, maybe Java isn't the right tool for the job, but my gut instinct is to tell you that you're worrying about optimization too early, and that a Java version of your code, working with non-contiguous memory, will probably suit your needs.
I suggest using a HashMap (no threaded) or Hashtable (threaded) for your cache. Both store an object into an array in the sun jvm. Since all objects in java are passed by reference, this should be represented as an array of pointers in c. My bet is that you are performing premature optimization.
If you absolutely must have this, you have two options:
1) Use JNI and write it in c.
2) Get a BIG byte buffer and use ObjectOutputStream to write objects to it. This will probable be VERY SLOW compared to using a hash table.

determining java memory usage

Hmmm. Is there a primer anywhere on memory usage in Java? I would have thought Sun or IBM would have had a good article on the subject but I can't find anything that looks really solid. I'm interested in knowing two things:
at runtime, figuring out how much memory the classes in my package are using at a given time
at design time, estimating general memory overhead requirements for various things like:
how much memory overhead is required for an empty object (in addition to the space required by its fields)
how much memory overhead is required when creating closures
how much memory overhead is required for collections like ArrayList
I may have hundreds of thousands of objects created and I want to be a "good neighbor" to not be overly wasteful of RAM. I mean I don't really care whether I'm using 10% more memory than the "optimal case" (whatever that is), but if I'm implementing something that uses 5x as much memory as I could if I made a simple change, I'd want to use less memory (or be able to create more objects for a fixed amount of memory available).
I found a few articles (Java Specialists' Newsletter and something from Javaworld) and one of the builtin classes java.lang.instrument.getObjectSize() which claims to measure an "approximation" (??) of memory use, but these all seem kind of vague...
(and yes I realize that a JVM running on two different OS's may be likely to use different amounts of memory for different objects)
I used JProfiler a number of years ago and it did a good job, and you could break down memory usage to a fairly granular level.
As of Java 5, on Hotspot and other VMs that support it, you can use the Instrumentation interface to ask the VM the memory usage of a given object. It's fiddly but you can do it.
In case you want to try this method, I've added a page to my web site on querying the memory size of a Java object using the Instrumentation framework.
As a rough guide in Hotspot on 32 bit machines:
objects use 8 bytes for
"housekeeping"
fields use what you'd expect them to
use given their bit length (though booleans tend to be allocated an entire byte)
object references use 4 bytes
overall obejct size has a
granularity of 8 bytes (i.e. if you
have an object with 1 boolean field
it will use 16 bytes; if you have an
object with 8 booleans it will also
use 16 bytes)
There's nothing special about collections in terms of how the VM treats them. Their memory usage is the total of their internal fields plus -- if you're counting this -- the usage of each object they contain. You need to factor in things like the default array size of an ArrayList, and the fact that that size increases by 1.5 whenever the list gets full. But either asking the VM or using the above metrics, looking at the source code to the collections and "working it through" will essentially get you to the answer.
If by "closure" you mean something like a Runnable or Callable, well again it's just a boring old object like any other. (N.B. They aren't really closures!!)
You can use JMP, but it's only caught up to Java 1.5.
I've used the profiler that comes with newer versions of Netbeans a couple of times and it works very well, supplying you with a ton of information about memory usage and runtime of your programs. Definitely a good place to start.
If you are using a pre 1.5 VM - You can get the approx size of objects by using serialization. Be warned though.. this can require double the amount of memory for that object.
See if PerfAnal will give you what you are looking for.
This might be not the exact answer you are looking for, but the bosts of the following link will give you very good pointers. Other Question about Memory
I believe the profiler included in Netbeans can moniter memory usage also, you can try that

Categories

Resources