【问题标题】:Java: Size of a Vector in bytesJava:向量的大小(以字节为单位)
【发布时间】:2013-04-17 11:42:22
【问题描述】:

是否可以在 java 中以字节为单位获取 Vector 或 ArrayList 或任何对象的大小? size() 函数只给出元素的数量。但我想得到对象的实际大小。

【问题讨论】:

  • “但我想得到对象的实际大小。” 为什么?
  • 是的,只要您可以计算该向量/数组中单个对象的字节数
  • 一般你不需要知道这个,但是如果你真的做最简单的事情就是使用内存分析器。例如JDK自带的免费VisualVM。
  • @Andrew:我有一些 12 Vector 对象。我想看看哪个占用更多空间。基于此,我必须填充向量。这是一个安卓应用程序。我想让应用程序内存尽可能小。

标签: java android vector size


【解决方案1】:

目前,我实现了自己的以获取大小。

long sizeof(ArrayList<String> list)
{
    long size = 0;
    for(String s: list)
        size+=s.length();
    return size;
}

【讨论】:

  • 它不是那样工作的......每个字符串都有一个开销,列表本身有一个开销等等。
  • 这不是 OP 所要求的。他说大小以字节为单位,并没有提到 String ArrayList,只是对象。
  • @assylias:这个开销有多大可能会影响列表的整体大小?我假设上面的代码可以给我足够好的估计对象的大小。
  • 嗯...直到现在才意识到你是 OP:P
  • @rahul:这可以让您合理估计多个此类数组列表的相对大小。如果这就是您所需要的,那么这已经足够接近了,但它肯定不是“向量的大小(以字节为单位)”。
【解决方案2】:

不同的 JDK 对隐式对象有不同的大小。

您可以通过隐式对象大小乘以向量或数组列表的长度来计算它。 例如,如果您声明一个包含 10 条记录的整数数组,则 Java 整数是 32 位,即 32/8 = 4 字节。 您有 10 条记录,因此 10x4 = 40 字节。

在标准 java 中,字节 = 8 位,short=16bits,int=32bits,long=64bits。

【讨论】:

    【解决方案3】:

    首先:尝试阅读Does Java have an operator like "sizeof()" in C

    第二:Try this code:

    public class Sizeof
    {
        public static void main (String [] args) throws Exception
        {
            // Warm up all classes/methods we will use
            runGC ();
            usedMemory ();
            // Array to keep strong references to allocated objects
            final int count = 100000;
            Object [] objects = new Object [count];
    
            long heap1 = 0;
            // Allocate count+1 objects, discard the first one
            for (int i = -1; i < count; ++ i)
            {
                Object object = null;
    
                // Instantiate your data here and assign it to object
    
                object = new Object ();
                //object = new Integer (i);
                //object = new Long (i);
                //object = new String ();
                //object = new byte [128][3]
    
                if (i >= 0)
                    objects [i] = object;
                else
                {
                    object = null; // Discard the warm up object
                    runGC ();
                    heap1 = usedMemory (); // Take a before heap snapshot
                }
            }
            runGC ();
            long heap2 = usedMemory (); // Take an after heap snapshot:
    
            final int size = Math.round (((float)(heap2 - heap1))/count);
            System.out.println ("'before' heap: " + heap1 +
                                ", 'after' heap: " + heap2);
            System.out.println ("heap delta: " + (heap2 - heap1) +
                ", {" + objects [0].getClass () + "} size = " + size + " bytes");
            for (int i = 0; i < count; ++ i) objects [i] = null;
            objects = null;
        }
        private static void runGC () throws Exception
        {
            // It helps to call Runtime.gc()
            // using several method calls:
            for (int r = 0; r < 4; ++ r) _runGC ();
        }
        private static void _runGC () throws Exception
        {
            long usedMem1 = usedMemory (), usedMem2 = Long.MAX_VALUE;
            for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++ i)
            {
                s_runtime.runFinalization ();
                s_runtime.gc ();
                Thread.currentThread ().yield ();
    
                usedMem2 = usedMem1;
                usedMem1 = usedMemory ();
            }
        }
        private static long usedMemory ()
        {
            return s_runtime.totalMemory () - s_runtime.freeMemory ();
        }
    
        private static final Runtime s_runtime = Runtime.getRuntime ();
    } // End of class
    

    【讨论】:

      【解决方案4】:

      这应该显示内存使用情况

      Runtime rt = Runtime.getRuntime();
      long m0 = rt.totalMemory() -  rt.freeMemory();
      Object obj = new Object();      // create your object here
      long m1 = rt.totalMemory() -  rt.freeMemory();
      System.out.println(m1 - m0);
      

      但它不起作用。这有效(至少在我的电脑上)

      public static void main(String[] args) throws Exception {
          Object obj = createObject();
          long m0 = usedMem();
          long m1 = usedMem();
          obj = null;
          for (int i = 0; i < 100; i++)
              System.gc();
          m0 = usedMem();
          obj = createObject();
          for (int i = 0; i < 100; i++)
              System.gc();
          m1 = usedMem();
          System.out.println(m1 - m0);
      }
      
      private static long usedMem() {
          return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
      }
      
      private static Object createObject() {
          return new Object();
      }
      

      如果它为 new Object 打印 8 为 new String() 打印40 那么它工作正常,然后创建你的对象并查看它的大小

      在此处查看更多信息http://www.javaspecialists.eu/archive/Issue029.html

      【讨论】:

        猜你喜欢
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 2013-02-01
        • 2022-09-27
        • 2011-11-26
        • 2014-01-27
        • 2018-01-01
        • 2016-03-19
        相关资源
        最近更新 更多