wordpress中上传整站,手机网站百度关键词排名,wordpress 建站容易吗,做网站的公司都有哪些岗位优质博文#xff1a;IT-BLOG-CN
通过掌握每种数据类型的大小#xff0c;就可以更准确地预测对象和数据的内存消耗。
一、基础数据类型
Java基础数据类型结构#xff0c;在64位系统开启指针压缩情况下的内存占用字节数#xff1a;
booleanbytecharshortintlongfloatdoub…优质博文IT-BLOG-CN
通过掌握每种数据类型的大小就可以更准确地预测对象和数据的内存消耗。
一、基础数据类型
Java基础数据类型结构在64位系统开启指针压缩情况下的内存占用字节数
booleanbytecharshortintlongfloatdouble引用112248484
这些基础数据类型是轻量级的应尽可能多地使用他们以减少内存消耗。
二、对象内存占用情况
Java对象的内存占用包括标记字mark word、类指针klass pointer、数据字段实例变量以及填充padding
markwordklass pointerdatapadding84所有字段占用内存之和将内存占用补齐至8的整数倍
由此可见一个没有任何数据字段的空对象也会占用16字节的内存空间
三、数组内存占用
数组在Java中是一种特殊类型的对象它还包括一个额外的数组长度字段。数组的内存占用包括标记字、类指针、数组长度字段、数组元素以及填充。与对象类型数组的占用长度也必须是8的倍数。需要注意的是数组元素的大小取决于元素的类型和数量。
markwordklass pointer数组长度字段数组元素padding844所有字段占用内存之和将内存占用补齐至8的整数倍
四、String对象内存占用
这里我们以Java8为例说说空String的内存占用情况我们来看看String类中的成员变量。
/** The value is used for character storage. */
private final char value[];/** Cache the hash code for the string */
private int hash; // Default to 0/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID -6849794470754667710L;根据上面我们对对象和数组内存的分析以及String的成员属性可以得出一个空String对象所占用的内存空间如下所示。
对象头8 字节 引用 (4 字节 ) char 数组16 字节 1个 int4字节 1个long8字节 40 字节如果String字符串的长度大于0的话我们也可以得出String占用内存的计算公式如下所示。
40 2 * n五、内存占用分析工具
位了更准确地估计内存占用情况我们可以借助一些内存分析工具。 jol-core是一个java官方推出的jar包地址为GitHub-openjdk/jol
pom依赖
dependencygroupIdorg.openjdk.jol/groupIdartifactIdjol-core/artifactIdversion0.14/version
/dependencyJOL中常用的几个方法
ClassLayout.parseInstance(obj).toPrintable():查看对象内部的内存布局
ClassLayout.parseInstance(obj).instanceSize():计算对象的大小单位为字节GraphLayout.parseInstance(obj).toPrintable():查看对象外部信息包括引用的对象
GraphLayout.parseInstance(obj).totalSize():查看对象占用空间总大小注除了parseInstance(Object obj)外还有parseClass(Class? class)用法基本相同。
代码使用场景
public class JolTest {public static void main(String[] args) {Object obj new Test();// 查看对象内部信息System.out.println(ClassLayout.parseInstance(obj).toPrintable());}
}
class Test{private long p;private byte p1;private short p2;
}六、防止内存膨胀的策略
【1】使用基础类型代替String 在处理业务时短字符串如城市三字码频繁出现。标准String对象在Java中占用至少50字节内存这对于仅包含2-3个字符的字符串来说是一种浪费。我们可以使用CodeUtil工具将这些字符串编码为原生数据类型从而显著降低内存占用并可能提升性能。
将字符串编码为浮点数和解码为字符串
public class Main {public static void main(String[] args) {String doubleString 123.45;// 将字符串编码为浮点数double encodedDouble CodeUtil.encodeToDouble(doubleString);System.out.println(Encoded Double: encodedDouble);// 将浮点数解码为字符串String decodedDoubleString CodeUtil.decodeFromDouble(encodedDouble);System.out.println(Decoded Double String: decodedDoubleString);String input Hello, World!;// 使用CodeUtil工具将字符串编码为char[]char[] encodedChars CodeUtil.encodeToCharArray(input);// 打印编码后的char数组System.out.println(Encoded char array:);for (char c : encodedChars) {System.out.print(c );}}
}输出
Encoded Double: 123.45
Decoded Double String: 123.45Encoded char array:
H e l l o , W o r l d !【2】使用对象池 在某些业务场景中可能存在大量完全相同或相似的对象。位了减少这些对象的内存占用可以使用对象池技术来重用这些对象。通过对象池我们可以确保相同的对象在内存中只有一份拷贝从而节省大量的内存空间。需要注意的是在使用对象池技术时需要确保对象的正确性和线程安全性。
【3】限制容器最大容量 HashMap等容器类在Java中广泛使用但他们没有容量上限。如果不断向容器中添加元素它们会持续扩容以及容纳更多的元素从而导致内存占用不断增加。为了避免这种情况的发生我们使用具有容量限制的容器类如Guava Cache来替代HashMap等无限制容器。这样可以将内存占用控制在一个合理范围内防止内存膨胀现象的发生。需要注意的是在设置容量限制时需要根据实际业务需求和系统性能进行合理权衡。