java string 内存_Java String 内存大小

本文详细分析了Java 8在64位环境中,使用-XX:+UseCompressedOops选项时,字符串及其子串的内存占用情况。通过探讨String对象和字符数组的内存布局,解释了空字符串和不同长度字符串的内存消耗,以及substring方法如何影响内存。内容还涉及到Java内存管理和优化的相关知识点。
摘要由CSDN通过智能技术生成

As Picture Down:

`java.lang.String`: #bytes: 5722104 #instances: 238421

5722104 / 238421 = 24, **why?**

f37a9cc728b6

222.jpg

openjdk version "1.8.0_202"

OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_202-b08)

OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.202-b08, mixed mode)

jinfo -flag UseCompressedOops 22592

-XX:+UseCompressedOops

3.18.6-2.el7.centos.x86_64 #1 SMP Mon Oct 24 13:01:33 CST 2016 x86_64 x86_64 x86_64 GNU/Linux

32Bit- Java 6

String Object:

First

a char array— thus a separate object— containing the actual characters; [4bytes, ) when no chars, it needs 4 at least

an integer offset into the array at which the string starts; 4bytes

the length of the string; 4bytes

another int for the cached calculation of the hash code. 4bytes

Add Plus Object Header 8 bytes.

4+4*3+8 = 24 bytes! This gives 24 bytes (which is a multiple of 8 so no "padding" bytes are needed so far).

Second

Underlying char array: 16 bytes.

The empty char array: 12bytes

4bytes: length

8bytes: object header

And, plus 4 bytes to padding.

So, Actually, empty String needs 40bytes!

More Deep

1. 17 charactes String:

char array: 17*2 = 34 bytes, plus empty char array 12bytes -> 46bytes.

after Padding -> 48 bytes (a multiple of 8)

So 48 + 24 =** 72 btyes!**

when use C programming, it only 18bytes!

2. SubString

substring will share parent char array. So,

if you keep on to the parent string after creating the substring, then you will save memory overall;

if you throw away the parent string after creating the substring, then you will waste memory (if the substring is shorter than the parent).

For example, in the following code:

String str = "Some longish string...";

str = str.substring(5, 4);

It will waste memory, then we can create a new string instead.

String str = "Some longish string...";

str = new String(str.substring(5, 4));

64Bit-Java8

public final class String

implements java.io.Serializable, Comparable, CharSequence {

/** The value is used for character storage. */

private final char value[];

/** Cache the hash code for the string */

private int hash; // Default to 0

String Object: (-XX:-UseCompressedOops): 32bytes

a char array— thus a separate object— containing the actual characters; [8bytes, ) when no chars, it needs 8 at least

another int for the cached calculation of the hash code. 4bytes

Mark work + Class ptr 16bytes

padding 4bytes

String Object: (-XX:+UseCompressedOops): 24bytes

a char array— thus a separate object— containing the actual characters; [4bytes, ) when no chars, it needs 4 at least

another int for the cached calculation of the hash code. 4bytes

Mark work + Class ptr 8bytes + 4bytes

padding 4bytes

所以上例中24bytes,是因为java8 64bit 环境中,使用 -XX:+UseCompressedOops.

如果加上空数组的大小char[] value (16 bytes) 一共是40byte

SubString

java 8 中substring已经改由System.arraycopy实现,不再共用同一个char[].

/**

* Allocates a new {@code String} that contains characters from a subarray

* of the character array argument. The {@code offset} argument is the

* index of the first character of the subarray and the {@code count}

* argument specifies the length of the subarray. The contents of the

* subarray are copied; subsequent modification of the character array does

* not affect the newly created string.

*

* @param value

* Array that is the source of characters

*

* @param offset

* The initial offset

*

* @param count

* The length

*

* @throws IndexOutOfBoundsException

* If the {@code offset} and {@code count} arguments index

* characters outside the bounds of the {@code value} array

*/

public String(char value[], int offset, int count) {

if (offset < 0) {

throw new StringIndexOutOfBoundsException(offset);

}

if (count <= 0) {

if (count < 0) {

throw new StringIndexOutOfBoundsException(count);

}

if (offset <= value.length) {

this.value = "".value;

return;

}

}

// Note: offset or count might be near -1>>>1.

if (offset > value.length - count) {

throw new StringIndexOutOfBoundsException(offset + count);

}

this.value = Arrays.copyOfRange(value, offset, offset+count); // System.arraycopy

}

/**

* Returns a string that is a substring of this string. The

* substring begins with the character at the specified index and

* extends to the end of this string.

* Examples:

*

 
  

* "unhappy".substring(2) returns "happy"

* "Harbison".substring(3) returns "bison"

* "emptiness".substring(9) returns "" (an empty string)

*

*

* @param beginIndex the beginning index, inclusive.

* @return the specified substring.

* @exception IndexOutOfBoundsException if

* {@code beginIndex} is negative or larger than the

* length of this {@code String} object.

*/

public String substring(int beginIndex) {

if (beginIndex < 0) {

throw new StringIndexOutOfBoundsException(beginIndex);

}

int subLen = value.length - beginIndex;

if (subLen < 0) {

throw new StringIndexOutOfBoundsException(subLen);

}

return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);

}

引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值