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

Java程序可能非常渴望内存。 例如, Double对象有24个字节:8字节的数据和16字节的JVM开销。 一般来说,表示原始类型的对象非常昂贵。

对于Java标准库中的任何集合都会发生同样的情况。 因为HashSet里面包含一个HashMap (http://docs.oracle.com/javase/7/docs/api/java/util/HashSet。),所以甚至有一些违反直觉的事实,例如HashSetHashMap更渴望内存。 HTML)。

在高性能设置中建模数据和对象的委派时,您能否提出一些建议,以便减轻Java的这些“弱点”?


我用来减少内存的一些技巧:

  • 制作你自己的IntArrayList(etc)类来防止装箱
  • 创建你自己的IntHashMap(etc)类,其中键是基元
  • 使用nio的ByteBuffer可以有效地存储大量数据(并在本机内存中,堆外)。 它就像一个字节数组,但包含方法来存储/检索任何偏移量的缓冲区中的所有基元类型(交换内存以提高速度)
  • 不要使用缓冲池,因为缓冲池会将未使用的实例明确地保持活动状态
  • 很少使用线程,他们超级内存饿(在本机内存中,堆外)
  • 当生成大字符串的子字符串并丢弃原始字符时,子字符串仍然会引用原始字符串。 因此,使用new String来处理旧的大字符串。
  • 线性数组小于多维数组,并且如果除最后一个维以外的所有维的大小都是2的幂,则计算索引是最快的:对于16xN阵列, array[x|y<<4]
  • 使用初始容量初始化集合和StringBuilder ,以防止在典型情况下内部重新分配。
  • 使用StringBuilder而不是字符串连接,因为编译后的类文件使用new StringBuilder()而没有初始容量来连接字符串。

  • 取决于应用程序,但一般来说

  • 在(并行)基元数组中布局数据结构

  • 尝试制作大的“扁平”物体,否则就会形成合理的子结构

  • 专门化原始图集

  • 重用对象,使用对象池,ThreadLocals

  • 离开堆

  • 我不能说这些做法是“最好的”,因为不幸的是,它们让你感到痛苦,失去了使用Java的原因,降低了代码库的灵活性,可支持性,可靠性,可测试性和其他“良好”属性。

    但是,它们肯定会降低内存占用和GC压力。


    在Java中容易忽视的内存问题之一是内存泄漏。 尼古拉斯格林已经指出你记忆分析。

    许多人认为Java的垃圾收集可以防止内存泄漏,但事实并非如此 - 只需要一个被遗忘的引用来永久保留对象。 矛盾的是,试图优化你的程序可能会带来更多的内存泄漏机会,因为你最终会遇到更复杂的数据结构。

    例如,如果您正在实施堆栈,则会出现内存泄漏的一个示例:

    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.
    

    正确的解决办法是:

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

    上一篇: What are some best practices to build memory

    下一篇: foreach changes in PHP7