0

I am facing challenging memory issues in my own application. I want to tackle a memory leakage problem, so instead of creating too many objects and arrays, I want to reuse the last allocated memory (using a pool of objects and arrays).

In one of my scenarios, I want to shift cells of an allocated array to the right for the specific length. For this, I implement the following simple solution:

private void shiftRight(int length) {
    for (int index = size + length - 1; index >= length; index--) {
        bytes[index] = bytes[index - length];
    }
}

As I google for this problem, I found that I can use System.arraycopy instead of my simple solution.

System.arraycopy(bytes, 0, bytes, length, size);

But I am worry about the performance of System.arraycopy. As mentioned in the documentation of this method:

If the src and dest arguments refer to the same array object, then the copying is performed as if the components at positions srcPos through srcPos+length-1 were first copied to a temporary array with length components and then the contents of the temporary array were copied into positions destPos through destPos+length-1 of the destination array.

This method uses a temporary array to copy from src to dest. I think this method causes a new performance issue by creating too many arrays in high transaction systems.

Could you please discuss about these two solutions?

Thanks in advance.

rghome
  • 8,529
  • 8
  • 43
  • 62
Hossein Mobasher
  • 4,382
  • 5
  • 46
  • 73
  • 3
    Could you just try it and see if the performance is acceptable? – mwarren Jun 19 '19 at 12:16
  • Implement and test the solution under high load has time cost for me. so, based on documentation, it seems to have performance issue. – Hossein Mobasher Jun 19 '19 at 12:19
  • 1
    Is this any help to you? https://stackoverflow.com/questions/18638743/is-it-better-to-use-system-arraycopy-than-a-for-loop-for-copying-arrays – mwarren Jun 19 '19 at 12:23
  • 2
    *"I want to tackle a memory leakage problem ..."* - If you really mean memory leak, then (IMO) you are going about solving the problem the wrong way. Use a memory profile to track down the source of the leak. It is much less work than rewriting your code to minimize object allocation. – Stephen C Jun 19 '19 at 13:18

1 Answers1

3

The key words in the sentence there are "as if". It doesn't actually use a temporary array. The description is simply saying that it works as if there was one (in other words, it doesn't overwrite things it should not).

You might like to compare performance of System.arraycopy vs the for loop as I believe I saw somewhere that the for loop can be quicker for short arrays.

See Is Java's System.arraycopy() efficient for small arrays?

rghome
  • 8,529
  • 8
  • 43
  • 62
  • We are not 100% sure that it doesn't create a temporary array. All we know is that it's a native method, but there's nothing to stop the native implementation from creating a temporary array. – Klitos Kyriacou Jun 19 '19 at 13:07
  • 1
    If we examine the source code of the native method (not hard!), we can be 100% sure. And we can be 99.9% sure without checking, because an implementation that *did* use a temporary array would have been optimized / fixed > 20 years ago. (Unless you are talking about an experimental JVM ... written by someone who didn't care much about performance.) – Stephen C Jun 19 '19 at 13:12
  • @Stephen C yes - 99.9%. The 0.1% is covered by this case: https://dilbert.com/strip/2009-08-30. – rghome Jun 19 '19 at 13:17
  • Yes. Funny. But not in this case. The code base is Open Source. Most likely, thousands of developers (Sun, Oracle, and outside) will have looked at that code over the years. If the native code implementation of `arraycopy` was egregiously bad, someone would have noted it, and (gleefully) blogged about it. – Stephen C Jun 19 '19 at 13:24
  • @StephenC I guess, inspecting the native code won't help as (according to the linked answer) it's an intrinsic. So we have to look elsewhere, too. That said, I agree with you that the code was reviewed many times. – maaartinus Jun 20 '19 at 10:37
  • 1
    @maaartinus normally intrinsic == native. – rghome Jun 20 '19 at 11:30
  • OK. In Java 11, `arraycopy` is implemented by a bunch of platform specific C++ generator classes that emit code for the numerous variant cases. However, the generator classes there for anyone to see ... and check ... and it doesn't involve any temporary arrays. (The source path for the x86_64 version is `jdk11/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp` if your want to look at it.) – Stephen C Jun 20 '19 at 13:08
  • 1
    @rghome AFAIK this is no more true. "native" means calling some non-java code and losing some [tens of instructions on it](https://stackoverflow.com/a/13977914/581205), while "intrinsic" means special handling doing whatever the JIT sees fit, possibly without any call overhead. A good example for this is `Long.rotateRight` which takes a single instruction on current CPUs, [even in Java](https://stackoverflow.com/a/12770820/581205). This can't be optimized using a JNI call as *any* call is much more expensive than the non-optimized shift-shift-or implementation. – maaartinus Jun 20 '19 at 18:03
  • 2
    @maaartinus - My understanding is that `native` and 'intrinsic' are orthogonal. But it depends on whether you mean "native" to mean implemented in native code or declared with the `native` keyword. – Stephen C Jun 20 '19 at 23:01
  • Since we are going a bit off-topic (in respect of the original question) on intrinsics vs native/JNI, I created a new question to expand on this point: https://stackoverflow.com/questions/56698783/what-is-the-difference-between-java-intrinsic-and-native-methods. – rghome Jun 21 '19 at 07:28