简体   繁体   English

字符串不可变性记忆问题

[英]String Immutability memory Issue

Once the String object is created , we can't modify it But if we do any operations on it JVM will create New Object. 一旦创建了String对象,我们就无法修改它但是如果我们对它进行任何操作,JVM将创建New Object。 Here by creating new objects then JVM consumes more memory. 这里通过创建新对象,JVM消耗更多内存。 Then i think it causes to memory issue right.? 然后我认为这会导致记忆问题正确。

You are correct. 你是对的。 It is definitely worth being aware of this issue, even if it doesn't affect you every time. 这绝对是值得意识到这个问题,即使不每次都影响到你。

As you say, Strings cannot change after creation - they're immutable and they don't expose many ways to change them. 正如你所说,字符串在创建后无法改变 - 它们是不可变的,并且它们没有暴露出许多改变它们的方法。

However, operations such as a split() will be generating additional string objects in the background, and each of those strings have a memory overhead if you are holding onto references to them . 但是,诸如split()之类的操作将在后台生成其他字符串对象,并且如果您持有对它们的引用,则每个字符串都会产生内存开销

As the other posters note, the objects will be small and garbage collection will usually clean up the old ones after they have gone out of scope, so you generally won't have to worry about this. 正如其他海报所指出的那样,对象会很小,垃圾收集通常会在它们超出范围后清理旧的,所以你通常不必担心这个问题。

However, if you're doing something specific and holding onto large amounts of string references then this could bite you. 但是,如果你正在做一些特定的事情并持有大量的字符串引用,那么这可能会让你感到害怕。

Look at String interning depending on your use case, noting the warnings on the linked page. 根据您的使用情况查看String interning ,并注意链接页面上的警告。

Two things to note: 有两点需要注意:

1) Hard coded String literals will be automatically interned by Java, reducing the impact of this. 1)硬编码的字符串文字将由Java 自动实现 ,减少了这种影响。

2) The + operator is more efficient in this regard, it will use String Builders underneath giving performance & memory benefits. 2)+运算符在这方面效率更高,它将使用String Builders来提供性能和内存优势。

No, that does not. 不,那不是。 If you do not hold strong links to String instances they eventually will be collected by a garbage collector. 如果您没有持有String实例的强链接,它们最终将被垃圾收集器收集。

For example: 例如:

while (true) {
    new String("that is a string");
}

in this snippet you continuously create new object instances, however you will never get OutOfMemoryException as created instances become garbage (there are obviously no strong links). 在这个片段中,你不断创建新的对象实例,但是你永远不会得到OutOfMemoryException,因为创建的实例变成了垃圾(显然没有强大的链接)。

It consumes more memory for new objects, that's right. 它为新对象消耗更多内存,这是正确的。 But that fact in itself does not create an issue, because garbage collector promptly reclaims all inaccessible memory. 但是这个事实本身并不会产生问题,因为垃圾收集器会立即回收所有无法访问的内存。 Of course you can turn it into an issue by creating links to the newly created strings, but that would be an issue of your program, not of JVM. 当然,您可以通过创建指向新创建的字符串的链接将其转换为问题,但这将是您的程序的问题,而不是JVM的问题。

The biggest memory issue you have to know about is taking a small substring of a huge string. 你必须要知道的最大内存问题是使用一个巨大字符串的小子串。 That substring shares the original string's char array and even if the original string gets gc'd, the huge char array will still be referenced by the substring. 该子串共享原始字符串的char数组,即使原始字符串获得gc'd,子字符串仍将引用巨大的char数组。 The workaround is to use new String(hugeString.substring(i)) . 解决方法是使用new String(hugeString.substring(i))

The issue that is generated is the fact that garbage is generated. 生成的问题是生成垃圾的事实。 This issue is resolved by the virtual machine by calling the garbage collector which frees the memory used by that garbage. 虚拟机通过调用垃圾收集器来解决此问题,垃圾收集器释放垃圾使用的内存。

As soon as the old object is not used anymore, it can be removed by the garbage collector. 一旦旧对象不再使用,它​​就可以被垃圾收集器删除。 (Which will be done far before any memory issue arises). (这将在出现任何内存问题之前完成)。

If you want to prevent the copying of the data, use a StringBuilder. 如果要防止复制数据,请使用StringBuilder。

Unused objects are collected by GC. GC收集未使用的对象。

and Immutability got many benefits in java. 和Immutability在java中有很多好处。

In Java achieving as much immutability as possible is a good practice. 在Java中,实现尽可能多的不变性是一种很好的做法。

They can be safely used in Collections frameworks also. 它们也可以安全地用在Collections框架中。

Check this 检查一下

As far as I know StringBuilder (or StringBuffer for thread safe) is useful for managing String and make them mutable. 据我所知, StringBuilder (或线程安全的StringBuffer )对于管理String并使它们可变是有用的。

Manipulate some characters in a huge String do not 'eat' many bytes in memory. 操纵一个巨大的字符串中的一些字符不要“吃掉”内存中的许多字节。

It is also more powerful/speed for concate. 它也更强大/速度更快。

Since a string instance is immutable it can be reused by the jvm. 由于字符串实例是不可变的,因此可以由jvm重用。 The String class is implemented with Flyweight Design Pattern that is used to avoid memory issues. String类使用Flyweight设计模式实现,用于避免内存问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM