对于Java中的这种情况,为什么原始数据类型比参考数据类型消耗更多的内存?

Kawser Habib博士

我试图检查程序的内存消耗。在检查过程中,我注意到了一些有趣的事情。

我创建了一个Load类,其中包含一些字段。

class Load {
    String name;
    String title;
    long id;
}

我创建了500000个Load对象,并将它们添加到ArrayList中。我发现,它占用18 MB了内存。

然后,我修改了Load类并使用referenceLong类型。

class Load {
    String name;
    String title;
    Long id;
}

再次创建500000 Load对象并将其添加到ArrayList。有趣的是,这次比以前占用更少的内存。14 MB。

运行更改操作系统和JVM版本的测试。发现以下结果。

OS: Windows 10 Pro 64 bit
JDK: 11 64bit
 
Object Created  | Load Object         | Memory | Load Object         | Memory  
------------------------------------------------------------------------------
1. 500000       | With primitive long | 18 MB  | With reference Long | 14 MB
2. 900000       |                     | 32 MB  |                     | 26 MB
3. 1500000      |                     | 53 MB  |                     | 41 MB

OS: macOS Big Sur 64 bit
JDK: 8 64bit
 
Object Created  | Load Object         | Memory | Load Object         | Memory  
------------------------------------------------------------------------------
1. 500000       | With primitive long | 18 MB  | With reference Long | 14 MB
2. 900000       |                     | 32 MB  |                     | 26 MB
3. 1500000      |                     | 53 MB  |                     | 41 MB

出乎意料的是,在所有这些测试运行中,Object所包含的基本类型long所消耗的内存比Object所引用的Long所消耗的内存更多。

我的问题是,为什么在这种情况下原始类型会占用更多的内存?

内存测试器代码:

public class MemoryChecker {

    private static final long MEGABYTE = 1024L * 1024L;

    public static long bytesToMegabytes(long bytes) {
        return bytes / MEGABYTE;
    }

    public static void main(String[] args) {
        List<Load> list = new ArrayList<Load>();
        for (int i = 0; i <= 500000
                ; i++) {
            list.add(new Load("Jim", "Knopf", 11L));
        }
        // Get the Java runtime
        Runtime runtime = Runtime.getRuntime();
        // Run the garbage collector
        runtime.gc();
        // Calculate the used memory
        long memory = runtime.totalMemory() - runtime.freeMemory();
        System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
    }
}

完成代码git repo

霍尔格

对于32位JVM,对于具有CompressedOOPs功能的64位JVM (HotSpot JVM支持,默认情况下处于启用状态),引用仅消耗4个字节,而a则为8个字节long

即使使用实际对象初始化引用,共享对象时也可能消耗更少的内存这适用于常量自动装箱

如果值p被装箱是评估一个常量表达式(结果§15.29类型的)booleanbytecharshortint,或long,其结果是truefalse在的范围内的字符'\u0000',以'\u007f'包容,或在范围内的整数-128,以127包容,然后让a并且b成为的任意两次装箱转换的结果p总是这样的a == b

而且还涉及到所有Long.valueOf(long)通常以结束的操作

此方法将始终缓存-128至127(包括)范围内的值,并且可能缓存该范围之外的其他值。

当然,如果创建许多未共享的Long对象,则它们将比原始对象消耗更多的内存long如果您使用许多不同的值,那么即使潜在地共享它们也无济于事。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

对于Java中的这种情况,为什么原始数据类型比参考数据类型消耗更多的内存?

来自分类Dev

在Java中,为什么String是非原始数据类型?

来自分类Dev

为什么“where”改变原始数据类型

来自分类Dev

从Java中的catch块返回原始数据类型

来自分类Dev

为什么Java在声明原始数据类型时不允许null

来自分类Dev

覆盖原始数据类型的转换

来自分类Dev

如何检测原始数据类型?

来自分类Dev

验证原始数据类型

来自分类Dev

为什么原始数据类型可以在不包含系统名称空间的情况下工作?

来自分类Dev

什么因素决定了原始数据类型的大小?

来自分类Dev

什么因素决定了原始数据类型的大小?

来自分类Dev

XML模式世界中的黑白原始数据类型和派生数据类型有什么区别?

来自分类Dev

Java原始数据类型在堆栈还是堆上?

来自分类Dev

如何在Java的原始数据类型定义/写的?

来自分类Dev

Java语言中的原始数据类型

来自分类Dev

了解JavaScript中的原始数据类型

来自分类Dev

PERL中的JSON解码-保持原始数据类型

来自分类Dev

关于C#中的原始数据类型

来自分类Dev

在 Kotlin 中读取原始数据类型值

来自分类Dev

Javascript中的Refreence数据类型和原始数据类型

来自分类Dev

为什么要对char或数组以外的原始数据类型使用malloc?C

来自分类Dev

Drools 中原始数据类型与非原始数据类型的性能

来自分类Dev

为什么不同的数据类型会为相同的数据占用更多的内存?

来自分类Dev

Java中的原始数据类型和可移植性

来自分类Dev

是否可以在Java中创建自己的原始数据类型。像int,float,double

来自分类Dev

我如何将原始数据类型与Java中的泛型区分开?

来自分类Dev

$ .makeArray()在“真实”数组和原始数据类型上

来自分类Dev

将通用参数转换为原始数据类型

来自分类Dev

双类别vs双原始数据类型

Related 相关文章

  1. 1

    对于Java中的这种情况,为什么原始数据类型比参考数据类型消耗更多的内存?

  2. 2

    在Java中,为什么String是非原始数据类型?

  3. 3

    为什么“where”改变原始数据类型

  4. 4

    从Java中的catch块返回原始数据类型

  5. 5

    为什么Java在声明原始数据类型时不允许null

  6. 6

    覆盖原始数据类型的转换

  7. 7

    如何检测原始数据类型?

  8. 8

    验证原始数据类型

  9. 9

    为什么原始数据类型可以在不包含系统名称空间的情况下工作?

  10. 10

    什么因素决定了原始数据类型的大小?

  11. 11

    什么因素决定了原始数据类型的大小?

  12. 12

    XML模式世界中的黑白原始数据类型和派生数据类型有什么区别?

  13. 13

    Java原始数据类型在堆栈还是堆上?

  14. 14

    如何在Java的原始数据类型定义/写的?

  15. 15

    Java语言中的原始数据类型

  16. 16

    了解JavaScript中的原始数据类型

  17. 17

    PERL中的JSON解码-保持原始数据类型

  18. 18

    关于C#中的原始数据类型

  19. 19

    在 Kotlin 中读取原始数据类型值

  20. 20

    Javascript中的Refreence数据类型和原始数据类型

  21. 21

    为什么要对char或数组以外的原始数据类型使用malloc?C

  22. 22

    Drools 中原始数据类型与非原始数据类型的性能

  23. 23

    为什么不同的数据类型会为相同的数据占用更多的内存?

  24. 24

    Java中的原始数据类型和可移植性

  25. 25

    是否可以在Java中创建自己的原始数据类型。像int,float,double

  26. 26

    我如何将原始数据类型与Java中的泛型区分开?

  27. 27

    $ .makeArray()在“真实”数组和原始数据类型上

  28. 28

    将通用参数转换为原始数据类型

  29. 29

    双类别vs双原始数据类型

热门标签

归档