我试图检查程序的内存消耗。在检查过程中,我注意到了一些有趣的事情。
我创建了一个Load类,其中包含一些字段。
class Load {
String name;
String title;
long id;
}
我创建了500000个Load对象,并将它们添加到ArrayList中。我发现,它占用18 MB
了内存。
然后,我修改了Load类并使用reference
Long类型。
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类型的)
boolean
,byte
,char
,short
,int
,或long
,其结果是true
,false
在的范围内的字符'\u0000'
,以'\u007f'
包容,或在范围内的整数-128
,以127
包容,然后让a
并且b
成为的任意两次装箱转换的结果p
。总是这样的a == b
。
而且还涉及到所有Long.valueOf(long)
通常以结束的操作。
此方法将始终缓存-128至127(包括)范围内的值,并且可能缓存该范围之外的其他值。
当然,如果创建许多未共享的Long
对象,则它们将比原始对象消耗更多的内存long
。如果您使用许多不同的值,那么即使潜在地共享它们也无济于事。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句