11

I recenty came across sun.misc.Unsafe class, allowing user to allocate,deallocate and in general access memory in a similar fashion like in C. I read in a couple of blogs that tackle this issue e.g.

  1. Which is faster - heap or direct memory - test results claim heap
  2. Off-heap memory vs DirectByteBuffer vs Heap - Off-heap seems to be fastest
  3. Memory mapped files for time series data - MappedByteBuffer faster than heap objects

Article 1) seems to be in contradiction with the other ones and I fail to comprehend why. DirectMemoryBuffer is using sun.misc.Unsafe under the hood (so is MappedByteBuffer), so they should also suffer from JNI calls as described in article 1. Also, in article 2, the Off-heap memory accesses resemble the ones in article 1, and give completely opposite results.

Could someone generally comment on how to proceed with Off-heap memory i.e. when to use it, is there a significant benefit to it, and most importantly, why similar subject gives highly different results based on the articles above? Thanks.

trincot
  • 317,000
  • 35
  • 244
  • 286
Bober02
  • 15,034
  • 31
  • 92
  • 178
  • Any time you use Unsafe or go off to a native method you pay an initial overhead, just to get there and set things up. As such, even if there is a (slight) performance advantage, it doesn't "kick in" unless you're dealing with fairly large (megabyte-sized) data structures. As to when to use these facilities, until you can answer your own questions above you should not use them -- it's really easy to eff things up, for very little benefit. – Hot Licks Mar 11 '14 at 18:19
  • @Hot Licks: OK, I get that point. Now my further question is - if I have 1000 objects of size 10 bytes, and I call 1000 times `Unsafe.putInt` (once per each object address), how does that differ from calling 1000 times `Unsafe.putInt` on 10,000 byte object, each time with a different offset i.e. 0, then 4, 8 etc? Where is the performance gain, since we should be crossing the JNI barrier exactly 1000 times in both cases? – Bober02 Mar 11 '14 at 18:23
  • To move only 10 bytes (or 4, if it's really putInt) there's probably no performance gain in either scenario. – Hot Licks Mar 11 '14 at 18:39
  • Well not according to the article, which is precisely what is puzzling me... – Bober02 Mar 11 '14 at 18:40
  • Understand that "the heap" is not this encapsulated hunk of something that you have to pry apart every time you access it. Rather it's the "soup" that your Java program is floating in, and accessing it is as easy as performing a single "load" instruction in the CPU. Using Unsafe is only better when it lets you do, um, "unsafe" things, such as copying data directly from a byte array to an int array. Even the a standard `int[]` to `int[]` array copy is going to be as fast or faster using System.arraycopy vs going off to Unsafe. – Hot Licks Mar 11 '14 at 18:45
  • (And understand that you can create a benchmark to prove just about anything you want.) – Hot Licks Mar 11 '14 at 18:47
  • Thanks, so what are the recommendations for using the Unsafe then? When allocating a big chunk of memory, when using MemoryMappedFiles... ? – Bober02 Mar 11 '14 at 18:49
  • When you need it. Memory-mapped files is perhaps one case (though I'm thinking that nio can handle some of that without having to explicitly use Unsafe). And, of course, if you use reflections you're using it implicitly. – Hot Licks Mar 11 '14 at 18:59
  • Here's a fairly good overview: http://www.javacodegeeks.com/2013/12/the-infamous-sun-misc-unsafe-explained.html (Note in particular how complicated -- and slow -- the authorization check is.) – Hot Licks Mar 11 '14 at 19:00
  • The 1st link requires credentials. Either remove it or even better replace it with another. – Mike Argyriou Feb 22 '18 at 12:08

1 Answers1

9

1). Working with Native memory from Java has its usages such as when you need to work with large amounts of data (> 2 gigabytes) or when you want to escape from the garbage collector. However in terms of latency, direct memory access from the JVM is not faster than accessing the heap as demonstrated above. The results actually make sense since crossing the JVM barrier must have a cost. That’s the same dilema between using a direct or a heap ByteBuffer. The speed advantage of the direct ByteBuffer is not access speed but the ability to talk directly with the operating system’s native I/O operations. Another great example discussed by Peter Lawrey is the use of memory-mapped files when working with time-series.

Source: http://mentablog.soliveirajr.com/2012/11/which-one-is-faster-java-heap-or-native-memory/

2). Off heap via Unsafe is blazing fast with 330/11200 Million/Sec. Performance for all other types of allocation is either good for read or write, none of the allocation is good for both. Special note about ByteBuffer, it is pathetic , i am sure you will not use this after seeing such number. DirectBytebuffer sucks in read speed, i am not sure why it is so slow.So if memory read/write is becoming bottle neck in your system then definitely Off-heap is the way to go, remember it is highway, so drive with care.

Soruce: http://www.javacodegeeks.com/2013/08/which-memory-is-faster-heap-or-bytebuffer-or-direct.html

MGot90
  • 2,422
  • 4
  • 15
  • 31
  • From article 2: "For memory allocation test I will use 13 byte of message & it is broken down into...". It seems the writes are quite small, not with big chunks and it is being constantly crossed when invoking `Unsafe` method. So I am still not getting how the tests differ and where the discrepancies lie. – Bober02 Mar 11 '14 at 18:20
  • Yes I feel thats where this article falls short. With respect to memory allocation he only test write/read performance and totally ignores memory consumption/allocation speed. Something involving this (which he never looks at) would probably explain why it is being constantly crossed when invoking Unsafe method. – MGot90 Mar 11 '14 at 18:24
  • Well, the other article also ignores the fact of allocation/deallocation for testing read/write access right? That is, purely test read/write access, yet gets much different results... – Bober02 Mar 11 '14 at 18:33
  • It should be noted that there is no difference between the performance of "off heap" vs heap memory -- it's the exact same memory, and the fact that it's heap adds no overhead. – Hot Licks Mar 11 '14 at 18:50