String字符串详解

参考文章

参考1–基础
参考2
参考3
参考4–重点
环境:JDK1.8

事件描述

由于公司的需要需要从日志中拉取一些重要的数据,于是通过readLine方法来获取数据,一个日志文件的大小500M-1G不等。于是思考,String字符串不是放常量池的吗?常连池是放在方法区,方法区属于永久区。那么如果这个项目当做一个拉取日志的项目,很有可能会把永久区给OOM。但是并没有发生这样的情况,那么让我们深入的了解下吧。

java的String发生的是哪种OOM

按照上面传统思维发生OOM应该是永久区报错:java.lang.OutOfMemoryError:PermGen space
实际情况jdk1.8的String常连池已经放到了堆里面,所以大量的字符串的创建并不会出现永久区的OOM,而是会出现堆的OOM即:java.lang.OutOfMemoryError:Java heap spacess
ps:当然jdk1.8永久区也已经改名字了改为( Metaspace)。

String的存储总结

对字符串不太了解的同学可以看下上面的3个参考地址。我这里只做下总结。
1:首先不管以何种方式创建String都会在字符串常量池中备份一个字符串。
2:只要不是新建字符串的情况,那么都会在编译期间确定String的存放位置和值。比如
String a=”helloworld”;
String b=”hello”+”world”;
a==b//true;
下面借用别人的图来表达一下常量池,栈,堆直接关系。
这里写图片描述
这里写图片描述
3:特别需要注意的是new String(),toString(),拼接”“,都是使用的堆中的对象。
Note:虽然有时候String是放在字符串池中,但是并不是意味着那个字符串一直存在,那个字符串隶属于当前的线程,如果当前的线程如果结束,那么这些String不管在堆里还是字符串池中都会被gc回收。这个字符串池和常量池还是有一定区别的,谨记不要搞混。
最后请思考下面这个问题:

public class Test {
    public static final String string2 = "java";
    public static void main(String[] args) {
        String string2 = "java";
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34796981/article/details/81536573