文件大小与Java中的内存大小
File size vs. in memory size in Java
如果我在磁盘上取一个大约2kB的XML文件,并在Java中将内容作为字符串加载到内存中,然后测量对象大小,它大约33kB
为什么尺寸会大幅增加?
如果我在c++中做同样的事情,内存中的结果字符串对象更接近2kB。
为了测量Java中的内存,我使用了Instrumentation。对于c++,我取序列化对象(例如string)的长度
我认为有多种因素。首先,正如Bruce Martin所说,java中的对象每个对象有16字节的开销,而c++没有。其次,Java中的字符串每个字符可能是2字节,而不是1字节。第三,可能是Java为string保留了比c++ std::string更多的内存。
假设您的XML文件主要包含ASCII字符,并使用将它们表示为单个字节的编码,那么您可以预期内存大小至少是两倍,因为Java内部使用UTF-16(尽管我听说有些jvm尝试优化这一点)。除此之外,还有2个对象(String实例和一个内部字符数组)和一些字段的开销,总共大约40字节。
所以你的"对象大小"33kb肯定是不正确的,除非你使用一个奇怪的JVM。你测量它的方法一定有问题
在Java字符串对象中有一些额外的数据,这增加了它的大小。
它是对象数据,数组数据和其他一些变量。可以是数组引用,偏移量,长度等。
String: String的内存增长跟踪其内部char数组的增长。但是,String类又增加了24字节的开销。对于大小为10个字符或更少的非空字符串,相对于有用负载(每个char 2字节加上4字节的长度),增加的开销成本范围为100%到400%。
:Java中对象的内存消耗是什么?
是的,您应该进行GC并给它时间来完成。只是system . gc ();并在循环中打印totalMem()。您还最好在数组中创建一百万个字符串副本(测量空数组的大小,然后用字符串填充),以确保您测量的是字符串的大小,而不是程序中可能出现的其他服务对象的大小。字符串本身不能占用32 kb。但是XML对象的层次结构可以。
说到这里,我无法抗拒在Java世界中没有人关心内存(和缓存命中)的讽刺。我们知道JIT正在改进,在某些情况下,它的性能可以超过本地c++代码。因此,不需要为内存优化而烦恼。初步优化是万恶之源。
如其他答案所述,Java的String增加了开销。如果您需要在内存中存储大量字符串,我建议您将它们存储为byte[]。这样,内存中的大小应该与磁盘上的大小相同。
String -> byte[]:
String a = "hello";
byte[] aBytes = a.getBytes();
byte[] -> String:
String b = new String(aBytes);
- 内存分配究竟是如何发生的,Java和C如何交互以跟踪同一对象?
- 如何在 ubuntu 上的 php 脚本中获取程序(c,c++,java,python,php)的执行时间和内存使用量?
- 如何从 JNI、Java 和 C++ 释放使用 jShortArray/jByteArray 分配的内存
- C++从 Java 角度设置和映射内存管理
- "new"会导致 Java 中的内存泄漏吗?
- 为什么 C++/Java 内存模型不包含条件变量
- 在 C/C++ 中获取 Java 对象的内存地址
- Java 调用的 C++ 内存泄漏
- 无法在 Mac OS X 上分配内存错误 - java(xx,xx) malloc: *** mmap(size=XX)
- 如果您以Java JNI分配的本机代码中的内存泄漏,会发生什么
- 对象如何存储在内存-Java(C )中
- Java 对象的内存预留
- 将C++内存排序映射到Java
- Java与C++内存分配
- Java和C++之间的共享内存
- OpenCV Java JNIEXPORT 内存管理
- 如何使用本机代码以编程方式查找Java本地变量的内存地址
- C++中内存泄漏本身存在多长时间,以及等效的Java程序有何不同
- 如何在使用JNI的C++/Java项目中使用CRT中的工具检测内存泄漏
- 是任何编程语言(C++、C#、Java、C.)中声明函数的最终内存地址,无论是相对地址还是绝对地址