Integer vs int: with regard to memory - java

I was wondering if there is a difference in the memory occupied by
Integer n, and int n.
I know int n occupies 4 bytes normally, how about Integer n

In general, the heap memory used by a Java object in Hotspot consists of:
an object header, consisting of a few bytes of "housekeeping" information;
memory for primitive fields, according to their size (int n->32 bits)
memory for reference fields (4 bytes each) (Integer n ->32 bits)
padding: potentially a few "wasted" unused bytes after the object data, to make every object start at an address that is a convenient multiple of bytes and reduce the number of bits required to represent a pointer to an object.
as per the suggestion of Mark Peters I would like add the link below
http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

An Integer object in Java occupies 16 bytes.
I don't know whether running a 64- vs 32-bit JVM makes a difference. For primitive types, it does not matter. But I can not say for certain how the memory footprint of an object changes (if at all) under a 64-bit system.
You can test this for yourself here:
Java Tip 130: Do you know your data size?

int is a primitive data type which takes 32 bits(4 bytes) to store.
When your Java code uses the new operator to create an instance of a Java object, much more
data is allocated than you might expect.
For example, it might surprise you to know that the size ratio of an int value to an Integer object — the smallest object that can hold an int value — is
typically 1:4.
Integer is an object which takes 128 bits (16 bytes) to store int value.
When we creates new Integer using new Operator it allocates memory as per follows.
Class Object(32 bits) - which consist of a pointer to the class information, which describes the object in our case its point to java.lang.Integer class
Flags (32 bits)- It is collection of flags that describes the state of object.
Like is it has hash-code, is it array or not i.e. its Shape.
Lock (32 bits) - It stores synchronization information of object. whether the object currently synchronized or not.
Above 3 points are called as metadata of an Object.
Lastly metadata is followed by the Object data (32 bits) itself. In case of Integer its single int value.
All the above explanation is as per 32 bit processor architecture. It can differ from JVM version and vendor.

For int: 4 bytes used per element without wrappers, and 16 per element with a wrapper.
A wrapped double reports as 24 bytes per element, with the actual double value as 64 bits (8 bytes).
For more details here

Related

What is the difference between Unsafe.putAddress and Unsafe.putLong methods?

What is the difference between Unsafe.putAddress(long address, long x) method and Unsafe.putLong(long address, long x) method?
The javadoc is pretty clear on that. For putAddress() it says:
The number of bytes actually written at the target address may be determined by consulting #addressSize.
Whereas putLong() puts all bits of the long value.
In other words: an address might consume all bits of a long value, but doesn't necessarily have to! And then writing 64 bit to somewhere in memory is most likely not a good idea!
Therefore you need to able to distinguish these two use cases (writing n bits out of 64 bits and writing exactly 64 bits).
But to be specific, the javadoc for address size says:
Report the size in bytes of a native pointer ... This value will be either 4 or 8.
So I guess, for all practical purpose, the two methods do the same. Because these days, (almost?!) all exist JVMs A) implement these methods and B) are 64 bit JVMs. ( so I assume that a 32 bit JVM would return 4 instead of 8 )

Is Byte implemented as Int anyway?

I had a java game book recommend implementing all data as Int when possible, that that type runs the fastest. It said the Byte, Char, and Boolean are implemented as Int anyway, so you don't save space and the casting you end up having to do in the code because of the Byte data will slow it down. For instance, a cast is needed for
a = (byte)(b+c);
since the addition result is an Int, even when a,b, and c are all declared as Bytes.
I currently have a huge 2D array declared as Byte for my game, to save space and for bitwise operations. Is it actually saving space? I've also seen bitwise operations done on Ints in examples, do bitwise operations work as expected on Ints?
This is generally incorrect. In fact, this is outlined in the JVM Specification §2.3:
The primitive data types supported by the Java Virtual Machine are the numeric types, the boolean type (§2.3.4), and the returnAddress type (§2.3.3).
The numeric types consist of the integral types (§2.3.1) and the floating-point types (§2.3.2).
The integral types are:
byte, whose values are 8-bit signed two's-complement integers, and whose default value is zero
short, whose values are 16-bit signed two's-complement integers, and whose default value is zero
int, whose values are 32-bit signed two's-complement integers, and whose default value is zero
long, whose values are 64-bit signed two's-complement integers, and whose default value is zero
char, whose values are 16-bit unsigned integers representing Unicode code points in the Basic Multilingual Plane, encoded with UTF-16, and whose default value is the null code point ('\u0000')
Now, for boolean it's slightly a different story. From §2.3.4:
Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.
You can see differences in the bytecode depending on whether you use a byte[] or an int[], so they're not identical:
byte[] b = {42};
ICONST_1
NEWARRAY T_BYTE
DUP
ICONST_0
BIPUSH 42
BASTORE
ASTORE 1
vs
int[] b = {42};
ICONST_1
NEWARRAY T_INT
DUP
ICONST_0
BIPUSH 42
IASTORE
ASTORE 1
Is it actually saving space?
Yes, it likely is, especially if the array is very large.
do bitwise operations work as expected on Ints?
Yes, they do.
It is true that byte + byte = int, requiring a cast, but bytes are implemented with 8 bits of data in memory, while ints are 32 bits. Therefore, using bytes will decrease the amount of memory that an array takes up by 4 times.
For example, if you had a 10 by 10 array of bytes, its size would be 800, but a 10 by 10 array of ints' size would be 3200.
More information on this
The answer depends on whether you are working with a single variable of type byte or with a byte array, byte[]. A byte array does indeed save space, with each Java byte using just a byte of memory (plus a constant amount of housekeeping data for the array object). However, a single local variable of type byte is actually stored as an int on the stack and takes the corresponding 4 bytes of memory. This is even expressed in the bytecode - there is the opcode baload - "Load byte or boolean from array" but there is no opcode for loading a byte from local variable like there is iload for ints. Similarily, local char and boolean variables actually are stored on the stack as an int and int-based opcodes are used to access them.
The entry 2.6.1 in JLS also says that all local variables take either one or two "slots" on the stack, so the single-slot types byte, char, float and int all take the same space. The JVM cannot address a unit smaller than a single such slot, so in the case of a byte, 3 bytes are so to say wasted.
To wrap it up: do use byte arrays to save space, but in the case of individual variables, using a byte instead of int won't save space and may even have a small negative performance impact (it may however be required if you need byte for the semantics, e.g. counter wrapping behavior and such).
Yes, when you perform a byte addition the return value is always an integer, reason being that 8bit + 8bit addition can always result in a value which is greater than 8bit.
e.g.
decimal | binary
255 | 1111 1111
121 | 0111 1001
376 | 1 0111 1000
So if you try to store it in a byte again will definitely result in loss of data.
Instead of 376 you would get "120" if typecasting to byte is done.
You can definitely use int instead of byte and also the bit wise operations work perfectly on int.
refer: http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm

How the byte data type can be useful for saving memory in large arrays

The byte data type is an 8-bit signed two's complement integer. It has
a minimum value of -128 and a maximum value of 127 (inclusive). The
byte data type can be useful for saving memory in large arrays, where
the memory savings actually matters. They can also be used in place of
int where their limits help to clarify your code; the fact that a
variable's range is limited can serve as a form of documentation.
I see this in java documentation.My question is how the byte data type will save the memory in large arrays?.I confused with this
Thanks in advance....
What it is saying is really very simple.
Suppose I have 40 "numbers" to store. If I store them in the following:
byte[] numbers = new byte[40];
it will take less space than if I store them in the following:
int[] numbers = new int[40];
Why? Because in an array, 40 byte instances occupies 40 bytes of memory, but 40 int instances occupies 40 x 4 = 160 bytes of memory.
Caveats:
Obviously, this only works if the numbers are small enough to be represented as byte ... without overflow; i.e. they must be in the range -128 to +127
This does NOT apply to simple variables. In Java a byte variable and an int variable typically occupy 4 bytes each. (It is a low-level JVM thing which would take a lot of explaining ...)
I'm glossing over the fact that heap memory may be allocated at a granularity that is coarser than 4 bytes. The allocation granularity is typically 8 bytes. However, for large arrays, the contribution of the allocation granularity is negligible. Likewise, I am glossing over the contribution of array headers for the above reason, AND because the contribution header is the same irrespective of the array's base type.
For instance you have an array of 1000000 integers. If you use int[] it will take up 4Mb of memory. But if you know that all values are within the range of -128 to 127 you can use byte[] and it will take up 4 times less memory

Java - indexing into array with a byte

Is it possible to index a Java array based on a byte?
i.e. something like
array[byte b] = x;
I have a very performance-critical application which reads b (in the code above) from a file, and I don't want the overhead of converting this to an int. What is the best way to achieve this? Is there a performance-decrease as a result of using this method of indexing rather than an int?
With many thanks,
Froskoy.
There's no overhead for "converting this to an int." At the Java bytecode level, all bytes are already ints.
In any event, doing array indexing will automatically upcast to an int anyway. None of these things will improve performance, and many will decrease performance. Just leave your code using an int.
The JVM specification, section 2.11.1:
Note that most instructions in Table 2.2 do not have forms for the integral types byte, char, and short. None have forms for the boolean type. Compilers encode loads of literal values of types byte and short using Java virtual machine instructions that sign-extend those values to values of type int at compile-time or runtime. Loads of literal values of types boolean and char are encoded using instructions that zero-extend the literal to a value of type int at compile-time or runtime. Likewise, loads from arrays of values of type boolean, byte, short, and char are encoded using Java virtual machine instructions that sign-extend or zero-extend the values to values of type int. Thus, most operations on values of actual types boolean, byte, char, and short are correctly performed by instructions operating on values of computational type int.
As all integer types in java are signed you have anyway to mask out 8 bits of b's value provided you do expect to read from the file values greater than 0x7F:
byte b;
byte a[256];
a [b & 0xFF] = x;
No; array indices are non-negative integers (JLS 10.4), but byte indices will be promoted.
No, there is no performance decrease, because on the moment you read the byte, you store it in a CPU register sometime. Those registers always works with WORDs, which means that the byte is always "converted" to an int (or a long, if you are on a 64 bit machine).
So, simply read your byte like this:
int b = (in.readByte() & 0xFF);
If your application is that performance critical, you should be optimizing elsewhere.

What is the purpose of long, double, byte, char in Java?

So I'm learning java, and I have a question. It seems that the types int, boolean and string will be good for just about everything I'll ever need in terms of variables, except perhaps float could be used when decimal numbers are needed in a number.
My question is, are the other types such as long, double, byte, char etc ever used in normal, everyday programming? What are some practical things these could be used for? What do they exist for?
With the possible exception of "short", which arguably is a bit of a waste of space-- sometimes literally, they're all horses for courses:
Use an int when you don't need fractional numbers and you've no reason to use anything else; on most processors/OS configurations, this is the size of number that the machine can deal with most efficiently;
Use a double when you need fractional numbers and you've no reason to use anything else;
Use a char when you want to represent a character (or possibly rare cases where you need two-byte unsigned arithmetic);
Use a byte if either you specifically need to manipulate a signed byte (rare!), or when you need to move around a block of bytes;
Use a boolean when you need a simple "yes/no" flag;
Use a long for those occasions where you need a whole number, but where the magnitude could exceed 2 billion (file sizes, time measurements in milliseconds/nanoseconds, in advanced uses for compacting several pieces of data into a single number);
Use a float for those rare cases where you either (a) are storing a huge number of them and the memory saving is worthwhile, or (b) are performing a massive number of calculations, and can afford the loss in accuracy. For most applications, "float" offers very poor precision, but operations can be twice as fast -- it's worth testing this on your processor, though, to find that it's actually the case! [*]
Use a short if you really need 2-byte signed arithmetic. There aren't so many cases...
[*] For example, in Hotspot on Pentium architectures, float and double operations generally take exactly the same time, except for division.
Don't get too bogged down in the memory usage of these types unless you really understand it. For example:
every object size is rounded to 16 bytes in Hotspot, so an object with a single byte field will take up precisely the same space as a single object with a long or double field;
when passing parameters to a method, every type takes up 4 or 8 bytes on the stack: you won't save anything by changing a method parameter from, say, an int to a short! (I've seen people do this...)
Obviously, there are certain API calls (e.g. various calls for non-CPU intensive tasks that for some reason take floats) where you just have to pass it the type that it asks for...!
Note that String isn't a primitive type, so it doesn't really belong in this list.
A java int is 32 bits, while a long is 64 bits, so when you need to represent integers larger than 2^31, long is your friend. For a typical example of the use of long, see System.currentTimeMillis()
A byte is 8 bits, and the smallest addressable entity on most modern hardware, so it is needed when reading binary data from a file.
A double has twice the size of a float, so you would usually use a double rather than a float, unless you have some restrictions on size or speed and a float has sufficient capacity.
A short is two bytes, 16 bits. In my opinion, this is the least necessary datatype, and I haven't really seen that in actual code, but again, it might be useful for reading binary file formats or doing low level network protocols. For example ip port numbers are 16 bit.
Char represents a single character, which is 16 bits. This is the same size as a short, but a short is signed (-32768 to 32767) while a char is unsigned (0 to 65535). (This means that an ip port number probably is more correctly represented as a char than a short, but this seems to be outside the intended scope for chars...)
For the really authorative source on these details, se the java language specification.
You can have a look here about the primitive types in Java.
The main interest between these types are the memory usage. For example, int uses 32bits while byte only uses 8bits.
Imagine that you work on large structure (arrays, matrices...), then you will better take care of the type you are using in order to reduce the memory usage.
I guess there are several purposes to types of that kind:
1) They enforce restrictions on the size (and sign) of variables that can be stored in them.
2) They can add a bit of clarity to code (e.g. if you use a char, then anyone reading the code knows what you plan to store in it).
3) They can save memory. if you have a large array of numbers, all of which will be unsigned and below 256, you can declare it as an array of bytes, saving some memory compared with if you declared an array of ints.
4) You need long if the numbers you need to store are larger than 2^32 and a double for very large floating point numbers.
The primitive data types are required because they are the basis of every complex collection.
long, double, byte etc. are used if you need only a small integer (or whatever), that does not waste your heap space.
I know, there's enough of RAM in our times, but you should not waste it.
I need the "small ones" for database and stream operations.
Integers should be used for numbers in general.
Doubles are the basic data type used to represent decimals.
Strings can hold essentially any data type, but it is easier to use ints and is confusing to use string except for text.
Chars are used when you only wish to hold one letter, although they are essentially only for clarity.
Shorts, longs, and floats may not be necessary, but if you are, for instance, creating an array of size 1,00000 which only needed to hold numbers less than 1,000, then you would want to use shorts, simply to save space.
It's relative to the data you're dealing with. There's no point using a data type which reserves a large portion of memory when you're only dealing with a small amount of data. For example, a lot of data types reserve memory before they've even been used. Take arrays for example, they'll reserve a default amount (say, 256 bytes <-- an example!) even if you're only using 4 bytes of that.
See this link for your answer

Categories