Are direct buffers in Java initialized to a default value like arrays? - java

When I initialize an array in Java like:
float[] array = new float[1000];
all elements are initialized to 0. Is that also the case when I allocate a direct buffer like this:
FloatBuffer buffer = ByteBuffer.allocateDirect(4*1000).asFloatBuffer();
? I always seem to get only zeroes, but perhaps it's implementation dependent...

It looks like the answer is probably.
Looking at the implementation of ByteBuffer, it uses DirectByteBuffer under the hood. Taking a look at the implementation source code of Android, it has this comment:
Constructs a new direct byte buffer of
the given capacity on newly allocated
OS memory. The memory will have been
zeroed.
So, when you allocate a buffer, all of the memory contents will be initialized to zero. The oracle implementation also does this zeroing.
This is an implementation detail though. Since the javadoc says nothing about the zeroing, it's technically incorrect to rely on it. To be correct, you should really zero the buffer yourself. In practice, if you're really worried about performance for some reason, you could leave it out, but be warned that some implementations of the JVM might not do this zeroing.

From the ducmentation to the parent abstract class Buffer:
The initial content of a buffer is, in general, undefined.
In the absence of anything to the contrary, I would assume that this applies to buffers allocated by ByteBuffer.allocateDirect(). Interestingly, I suppose that strictly it applies to ordinary array-backed buffers as well, though it is implicit in the allocation of a Java array that the array will be zeroed.

Looking at the Javadoc for Java 7 and also Java 8
it now says
The new buffer's position will be zero, its limit will be its
capacity, its mark will be undefined, and each of its elements will be
initialized to zero. Whether or not it has a backing array is
unspecified
So there is no longer any need for you to zero them yourself.

There is no way to tell so the question is futile. The initial position are zero so there is no API you can execute that will return a part of the buffer at hasn't been 'put' to yet.

Related

Should I Avoid Getting the Size of a Collection in a Loop?

According to https://www.geeksforgeeks.org/12-tips-to-optimize-java-code-performance/ at number 3, it says that during a for loop, you should define size beforehand and call that in the comparator. At first, that made sense to me assuming that the .size() method has to count up the elements every time it is called.
To verify this, I went to the source code for an ArrayList and went to the size method. What I found though was that it would just return an integer size that is stored as a value in the object. This is more of what I was expecting to find, but if this is the case, then why does the article say to avoid it? It does not explain why, it merely says to never do it. From what I saw, the list is already calling a variable that is stored in memory.
So, my question is: Is it actually going to help, or is it just something that the article got wrong?
The answer is: "it depends".
It depends on what List class you are using.
It depends on how smart the JIT compiler is.
It depends on whether the size of the list changes during the loop execution.
For the most common List implementations, the current size is held in a field, and the size() method simply returns that field. In such cases, the code of the size() method will typically be inlined so that a size() call is a efficient as accessing the field directly. If the JIT compiler is able to deduce that the field doesn't change (and if there are no relevant Java Memory Model related constraints) then it could conceivably cache the size() result in a register.
But the flipside is that some List implementations may compute the size, and the JIT compiler may not be able to do some or all of those optimizations.
But the flipside of the flipside is that if size() is cheap, the overhead of calling it on each loop iteration may be too small to be significant.
Bottom line:
Beware of premature optimization.
Beware of articles that give overly simplistic / overly generalized advice.
Beware of articles that contain arrant nonsense like this:
If possible, we can use primitive types instead of objects since data access from stack memory is faster than heap memory1.
1 - This appears in "5. Use Primitive Types Wherever Possible". Stack and heap memory use the same hardware and have the same access times. The real point he should be making in that context is that getting the value of an Integer involves an extra memory fetch, compared with accessing an int.
yes,it is actually going to help.
i think call a method is coast more time than use a variable。

Why can't object size be measured in a managed environment?

So a number of variations of a question exist here on stackoverflow that ask how to measure the size of an object (for example this one). And the answers point to the fact, without much elaboration, that it is not possible. Can somebody explain in length why is it not possible or why does it not make sense to measure object sizes?
I guess from the tags that you are asking about measurements of object sizes in Java and C#. Don't know much about C# therefore the following only pertains to Java.
Also there is a difference between the shallow and detained size of a single object and I suppose you are asking about the shallow size (which would be the base to derive the detained size).
I also interpret your term managed environment that you only want to know the size of an object at runtime in a specific JVM (not for instance calculating the size looking only at source code).
My short answers first:
Does it make sense to measure object sizes? Yes it does. Any developer of an application which runs under memory constraints is happy to know the memory implications of class layouts and object allocations.
Is it impossible to measure in managed environments? No it is not. The JVM must know about the size of its objects and therefore must be able to report the size of an object. If we only had a way to ask for it.
Long answer:
There are plenty of reasons why the object size cannot be derived from the class definition alone, for example:
The Java language spec only gives lowerbound memory requirements for primitive types. A int consumes at least 4 bytes, but the real size is up to the VM.
Not sure what the language spec tells about the size of references. Is there any constraint on the number of possible objects in a JVM (which would have implications for the size of internal storage for object references)? Today's JVMs use 4 bytes for a reference pointer.
JVMs may (and do) pad the object bytes to align at some boundary which may extend the object size. Todays JVMs usually align object memory at a 8 byte boundary.
But all these reasons do not apply to a JVM runtime which uses actual memory layouts, eventually allows its generational garbage collector to push objects around, and must therefore be able to report object sizes.
So how do we know about object sizes at runtime?
In Java 1.5 we got java.lang.instrument.Instrumentation#getObjectSize(Object).
The Javadoc says:
Returns an implementation-specific approximation of the amount of
storage consumed by the specified object. The result may include some
or all of the object's overhead, and thus is useful for comparison
within an implementation but not between implementations. The estimate
may change during a single invocation of the JVM.
Reading with a grain of salt this tells me that there is a reasonable way to get the exact shallow size of an object during one point at runtime.
Getting size of object is easily possible.
Getting object size may have little overhead if the object is large and we use IO streams to get the size.
If you have to get size of larger objects very frequently, you have to be careful.
Have a look at below code.
import java.io.*;
class ObjectData implements Serializable{
private int id=1;;
private String name="sunrise76";
private String city = "Newyork";
private int dimensitons[] = {20,45,789};
}
public class ObjectSize{
public static void main(String args[]){
try{
ObjectData data = new ObjectData();
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(b);
oos.writeObject(data);
System.out.println("Size:"+b.toByteArray().length);
}catch(Exception err){
err.printStackTrace();
}
}
}

Overhead of a Java JNI call [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What makes JNI calls slow?
First let me say that this questions is born more out of curiosity than real necessity.
I'm curious to know what is the overhead in doing a JNI call from Java, with say, System.arraycopy versus allocating the array and copying the elements over with a for loop.
If the overhead is substantial, then there is probably a rough "magic number" of elements up to which it compensates to simply use a for loop, instead of using the System call. And also, what exactly is involved in the System call that causes this overhead?
I'm guessing the stack must be pushed to the context of the call, and that might take a while, but I can't find a good explanation for the whole process.
Let me clarify my question:
I know that using arraycopy is the fastest way to copy an array in Java.
That being said, let's say I'm using it to copy an array of only one element. Since I'm calling the underlying OS to do so, there has to be an overhead in this call. I'm interested in knowing what this overhead is and what happens in the process of the call.
I'm sorry if using arraycopy misled you from the purpose of my question. I'm interested to know the overhead of a JNI call, and what's involved in the actual call.
Since I'm calling the underlying OS to do so...
You are right that system calls are fairly expensive. However, the System in System.arraycopy() is a bit of a misnomer. There are no system calls involved.
...there has to be an overhead in this call. I'm interested in knowing what this overhead is and what happens in the process of the call.
When you look at the definition of System.arraycopy(), it's declared as native. This means that the method is implemented in C++. If you were so inclined, you could look at the JDK source code, and find the C++ function. In OpenJDK 7, it's called JVM_ArrayCopy() and lives in hotspot/src/share/vm/prims/jvm.cpp. The implementation is surprisingly complicated, but deep down it's essentially a memcpy().
If arraycopy() is being used as a normal native function, there's overhead to calling it. There's further overhead caused by argument checking etc.
However, it's very likely that the JIT compiler knows about System.arraycopy(). This means that, instead of calling the C++ function, the compiler knows how to generate specially-crafted machine code to carry out the array copy. I don't know about other JVMs, but HotSpot does have such "intrinsic" support for System.arraycopy().
Let's say I'm using it to copy an array of only one element
If your array is tiny, you may be able to beat System.arraycopy() with a hand-crafted loop. You can probably do even better if the size is known at compile time, since then you can also unroll the loop. However, all of that is not really relevant except in the narrowest of circumstances.
Take a look at java.util.Arrays.copyOf implementations, eg
public static byte[] copyOf(byte[] original, int newLength) {
byte[] copy = new byte[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
they use System.arraycopy because this is the fastest way.
If you mean whether calling native methods in Java is expensive then take a look at http://www.javamex.com/tutorials/jni/overhead.shtml
UPDATE Question is really interesting, so I've done some testing
long t0 = System.currentTimeMillis();
byte[] a = new byte[100];
byte[] b = new byte[100];
for(int i = 0; i < 10000000; i++) {
// for(int j = 0; j < a.length; j++) {
// a[j] = b[j];
// }
System.arraycopy(b, 0, a, 0, a.length);
}
System.out.println(System.currentTimeMillis() - t0);
It shows that on very short arrays (< 10) System.arraycopy may be even slower, most probably because it's native, but on bigger arrays it does not matter anymore, System.arraycopy is much faster.
I'm interested to know the overhead of a JNI call, and what's involved in the actual call.
The System.arraycopy() method is rather complicated* and it is unlikely that the JIT compiler inlines it (as one of the other answers suggests).
On the other hand, it is likely the JIT compiler uses an optimized calling sequence, since this is an intrinsic native method. In other words, this is most likely not a normal JNI call.
* - System.arraycopy is not a simple memory copy. It has to test its arguments to avoid reading or writing beyond the array bounds, and so on. And in the case when you are copying from one object array to another it may need to check that actual type of each objects copied. All of this adds up to far more code than it is sensible to inline.
You have it the wrong way around. System.arraycopy() is a super fast native implementation provided by the JVM
There is no "overhead" - there is only "advantage"

what is the size of empty class in C++,java?

What is the size of an empty class in C++ and Java?
Why is it not zero?
sizeof(); returns 1 in the case of C++.
Short Answer for C++:
The C++ standard explicitly says that a class can not have zero size.
Long Answer for C++:
Because each object needs to have a unique address (also defined in the standard) you can't really have zero sized objects.
Imagine an array of zero sized objects. Because they have zero size they would all line up on the same address location. So it is easier to say that objects can not have zero size.
Note:
Even though an object has a non zero size, if it actually takes up zero room it does not need to increase the size of derived class:
Example:
#include <iostream>
class A {};
class B {};
class C: public A, B {};
int main()
{
std::cout << sizeof(A) << "\n";
std::cout << sizeof(B) << "\n";
std::cout << sizeof(C) << "\n"; // Result is not 3 as intuitively expected.
}
g++ ty.cpp
./a.out
1
1
1
In the Java case:
There is no simple way to find out how much memory an object occupies in Java; i.e. there is no sizeof operator.
There are a few ways (e.g. using Instrumentation or 3rd party libraries) that will give you a number, but the meaning is nuanced1; see In Java, what is the best way to determine the size of an object?
The size of an object (empty or non-empty) is platform specific.
The size of an instance of an "empty class" (i.e. java.lang.Object) is not zero because the instance has implicit state associated with it. For instance, state is needed:
so that the object can function as a primitive lock,
to represent its identity hashcode,
to indicate if the object has been finalized,
to refer to the object's runtime class,
to hold the object's GC mark bits,
and so on.
Current Hotspot JVMs use clever tricks to represent the state in an object header that occupies two 32 bit words. (This expands in some circumstances; e.g. when a primitive lock is actually used, or after identityHashCode() is called.)
1 - For example, does the size of the string object created by new String("hello") include the size of that backing array that holds the characters? From the JVM perspective, that array is a separate object!
Because every C++ object needs to have a separate address, it isn't possible to have a class with zero size (other than some special cases related to base classes). There is more information in C++: What is the size of an object of an empty class? .
Because an object has to have an address in memory, and to have an address in memory, it has to occupy "some" memory. So, it is usually, in C++, the smallest possible amount, i.e. 1 char (but that might depend on the compiler). In Java, I wouldn't be so sure.. it might have some default data (more than just a placeholder like in C++), but it would be surprising if it was much more than in C++.
C++ requires that a normal instantiation of it have a size of at least 1 (could be larger, though I don't know of a compiler that does that). It allows, however, an "empty base class optimization", so even though the class has a minimum size of 1, when it's used as a base class it does not have to add anything to the size of the derived class.
I'd guess Java probably does pretty much the same. The reason C++ requires a size of at least 1 is that it requires each object to be unique. Consider, for example, an array of objects with size zero. All the objects would be at the same address, so you'd really only have one object. Allowing it to be zero sounds like a recipe for problems...
It's defined by the C++ standard as "a nonzero value", because an allocated object must have a nonzero size in order to have a distinct address. A class that inherits from an empty class, however, is not required to increase in size, barring the usual increase of a vtable if there are virtual functions involved.
I don't know if there is a sizeof() operator in java. What you can do is create an instance of the empty class (have it serializable), send it through a PipedOutputStream and read it as byte array - byteArray.length gives you the size.
Alternatively, write out the instance to a file using DataOutputStream, close the File, open it and file.length() will give you the size of the Object. Hope this helps, - M.S.
As others have pointed out, C++ objects cannot have zero size. Classes can have zero size only when they act as a subclass of a different class. Take a look at #Martin York's answer for a description with examples --and also look and vote the other answers that are correct to this respect.
In Java, in the hotspot VM, there is a memory overhead of 2 machine-words (usually 4 bytes in a 32 arch per word) per object to hold book keeping information together with runtime type information. For arrays a third word is required to hold the size. Other implementations can take a different amount of memory (the classic Java VM, according to the same reference took 3 words per object)

What is the 'correct' way to store a native pointer inside a Java object?

What is the 'correct' way to store a native pointer inside a Java object?
I could treat the pointer as a Java int, if I happen to know that native pointers are <= 32 bits in size, or a Java long if I happen to know that native pointers are <= 64 bits in size. But is there a better or cleaner way to do this?
Edit: Returning a native pointer from a JNI function is exactly what I don't want to do. I would rather return a Java object that represents the native resource. However, the Java object that I return must presumably have a field containing a pointer, which brings me back to the original question.
Or, alternatively, is there some better way for a JNI function to return a reference to a native resource?
IIRC, both java.util.zip and java.nio just use long.
java.nio.DirectByteBuffer does what you want.
Internally it uses a private long address to store pointer value. Dah !
Use JNI function env->NewDirectByteBuffer((void*) data, sizeof(MyNativeStruct)) to create a DirectByteBuffer on C/C++ side and return it to Java side as a ByteBuffer. Note: It's your job to free this data at native side! It miss the automatic Cleaner available on standard DirectBuffer.
At Java side, you can create a DirectByteBuffer this way :
ByteBuffer directBuff = ByteBuffer.allocateDirect(sizeInBytes);
Think it as sort of C's malloc(sizeInBytes). Note: It has as automatic Cleaner, which deallocates the memory previously requested.
But there are some points to consider about using DirectByteBuffer:
It can be Garbage Collected (GC) if you miss your direct ByteBuffer reference.
You can read/write values to pointed structure, but beware with both offset and data size. Compiler may add extra spaces for padding and break your assumed internal offsets in structure. Structure with pointers (stride is 4 or 8 bytes ?) also puzzle your data.
Direct ByteBuffers are very easy to pass as a parameter for native methods, as well to get it back as return.
You must cast to correct pointer type at JNI side. Default type returned by env->GetDirectBufferAddress(buffer) is void*.
You are unable to change pointer value once created.
Its your job to free memory previously allocated for buffers at native side. That ones you used with env->NewDirectByteBuffer().
There is no good way. In SWT, this code is used:
int /*long*/ hModule = OS.GetLibraryHandle ();
and there is a tool which converts the code between 32bit and 64bit by moving the comment. Ugly but it works. Things would have been much easier if Sun had added an object "NativePointer" or something like that but they didn't.
A better way might by to store it in a byte array, since native pointers aren't very Java-ish in the first place. ints and longs are better reserved for storing numeric values.
I assume that this is a pointer returned from some JNI code and my advice would be just dont do it :)
Ideally the JNI code should pass you back some sort of logical reference to the resource and not an actual pointer ?
As to your question there is nothing that comes to mind about a cleaner way to store the pointer - if you know what you have then use either the int or long or byte[] as required.
You could look to the way C# handles this with the IntPtr type. By creating your own type for holding pointers, the same type can be used as a 32-bit or 64-bit depending on the system you're on.

Categories

Resources