What are some best practices to build memory

Java programs can be very memory hungry. For example, a Double object has 24 bytes: 8 bytes of data and 16 bytes of JVM-imposed overhead. In general, the objects that represent the primitive types are very expensive.

The same happens for any collection in the Java Standard Library. There are even some counterintuitive facts such as a HashSet being more memory hungry than a HashMap , since a HashSet contains a HashMap inside (http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html).

Could you come up with some advice when modeling data and delegation of objects in high performance settings so that these "weaknesses" of Java are mitigated?


Some techniques I use to reduce memory:

  • Make your own IntArrayList (etc) class that prevents boxing
  • Make your own IntHashMap (etc) class where keys are primitives
  • Use nio's ByteBuffer to store large arrays of data efficiently (and in native memory, outside heap). It's like a byte array but contains methods to store/retrieve all primitive types from the buffer at any arbitrary offset (trade memory for speed)
  • Don't use pooling because pools keep unused instances explicitly alive.
  • Use threads scarcely, they're super memory hungry (in native memory, outside heap)
  • When making substrings of big strings, and discarding the original, the substrings still refer to the original. So use new String to dispose of the old big string.
  • A linear array is smaller than a multidimensional array, and if the size of all but the last dimension is a power of two, calculating indices is fastest: array[x|y<<4] for a 16xN array.
  • Initialize collections and StringBuilder with an initial capacity chosen such that it prevents internal reallocation in a typical circumstance.
  • Use StringBuilder instead of string concatenation, because the compiled class files use new StringBuilder() without initial capacity to concatenate strings.

  • Depends on the application, but generally speaking

  • Layout data structures in (parallel) arrays of primitives

  • Try to make big "flat" objects, inlining otherwise sensible sub-structures

  • Specialize collections of primitives

  • Reuse objects, use object pools, ThreadLocals

  • Go off-heap

  • I cannot say these practices are "best", because they, unfortunately, make you suffer, losing the point why you are using Java, reduce flexibility, supportability, reliability, testability and other "good" properties of the codebase.

    But, they certainly allow to lower memory footprint and GC pressure.


    One of the memory problems that are easy to overlook in Java is memory leakage. Nicholas Greene already pointed you to memory profiling.

    Many people assume that Java's garbage collection prevents memory leaks, but that is not actually true - all it takes is one forgotten reference somewhere to keep an object around in perpetuity. Paradoxically, trying to optimize your program may introduce more opportunities for memory leaks because you end up with more complex data structures.

    One example for a memory leak if you are implementing, for instance, a stack:

    Integer stack[];
    stack = new Integer[10];
    int stackPtr = 0;
    
    // a few push operation on our stack.
    stack[stackPtr++] = new Integer(5);
    stack[stackPtr++] = new Integer(3);
    
    // and pop from the stack again
    --stackPtr;
    --stackPtr;
    
    // at this point, the stack is logically empty, but
    // the Integer objects are still referenced by the array,
    // and are basically leaked.
    

    The correct solution would have been:

    stack[--stackPtr] = null;
    
    链接地址: http://www.djcxy.com/p/39588.html

    上一篇: 加速Python

    下一篇: 构建内存的一些最佳实践是什么?