12

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...

Se Norm
  • 1,715
  • 5
  • 23
  • 40
  • 2
    Interesting question. The [ByteBuffer javadoc](http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html) doesn't seem to say anything in this matter. Do note however that the cases are slightly different. In the first case each element is initialized to `0.0f` while in the latter each float read being `0.0f` would just be due to the fact the [*bit pattern* for `0.0f` is "all zeros"](http://steve.hollasch.net/cgindex/coding/ieeefloat.html) in IEEE-754 –  Jul 03 '11 at 17:25
  • See my answer below: the ByteBuffer javadoc doesn't say anything, but the parent Buffer class does. – Neil Coffey Jul 03 '11 at 18:34

4 Answers4

5

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.

jterrace
  • 64,866
  • 22
  • 157
  • 202
  • 2
    I disagree : the comment is only an implementation comment, not a javadoc comment. And it is only in the Android implementation. The source code of the Oracle implementation doesn't include this comment, although it also sets the memory to 0. So my answer would be that it probably always is zeroed, but you can't be sure. – JB Nizet Jul 03 '11 at 18:02
  • Updated my answer to be more clear that this is an implementation detail. Thanks @jb-nizet – jterrace Jul 03 '11 at 18:06
  • See my answer below: it's a bit hidden, but the javadoc does actually imply that you CANNOT rely on the buffer definitely being zeroed. – Neil Coffey Jul 03 '11 at 18:29
  • 1
    @Neil Coffey it's not just implied, it is stated explicitly. – user207421 Jul 03 '11 at 23:11
3

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.

Community
  • 1
  • 1
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
3

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.

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
  • Im sure this answer was correct when you posted it, but it no longer is. – Paul Taylor Mar 03 '16 at 14:14
  • I think it was correct at the time, but as you say, it does look like this has been clarified in recent JDKs and direct buffers can be assumed to be zeroed. – Neil Coffey Mar 05 '16 at 22:16
0

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • What about buffer.get(int index)? I can do: FloatBuffer buf = ByteBuffer.allocateDirect(400).asFloatBuffer(); System.out.println(buf.get(7)); which outputs 0.0 – Se Norm Jul 06 '11 at 10:05
  • Surely it throws an underflow exception if nothing has been put there? – user207421 Jul 06 '11 at 12:50
  • it doesn't for me, to my knowledge the index is only checked against the buffers limit. An underflow exception is afaik only thrown if a relative access method is used and the limit is exceeded. Absolute get (as in get(int index) throws an out of bounds exception, but only if index>limit. – Se Norm Jul 06 '11 at 13:06
  • @Se Norm well I am a monkey's uncle, disregard me! – user207421 Jul 06 '11 at 23:45