博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阿里面试官:字符串在JVM中如何存放?90%的人就真的只回答在哪里存放
阅读量:5326 次
发布时间:2019-06-14

本文共 1099 字,大约阅读时间需要 3 分钟。

目录:

  1. 一道面试题的引出
  2. 案例分析
  3. intern 源码分析
  4. 总结

1. 一道面试题的引出

在面试BAT这种一线大厂时,如果面试官问道:字符串在 JVM 中如何存放?大多数人能顺利的给出如下答案:

 

字符串对象在JVM中可能有两个存放的位置:字符串常量池或堆内存。

  • 使用常量字符串初始化的字符串对象,它的值存放在字符串常量池中;
  • 使用字符串构造方法创建的字符串对象,它的值存放在堆内存中;

 

但是如果能针对上述回答,做进一步扩展,会给你的面试表现加分不少,让你从一大波候选人中脱颖而出。下面就一起来分析一下。

首先来看,String提供了一个API, java.lang.String.intern(),这个API可以手动将一个字符串对象的值转移到字符串常量池中

在1.7之前,字符串常量池是在PermGen区域,这个区域的大小是固定的,不能在运行时根据需要扩大,也不能被垃圾收集器回收,因此如果程序中有太多的字符串调用了intern方法的话,就可能造成OOM。

在1.7以后,字符串常量池移到了堆内存中,并且可以被垃圾收集器回收,这个改动降低了字符串常量池OOM的风险。

2. 案例分析

 

验证代码:

 

3. intern源码分析

我们来看intern方法的实现,intern方法的底层是一个native方法,在Hotspot JVM里字符串常量池它的逻辑在注释里写得很清楚:

如果常量池中有这个字符串常量,就直接返回,否则将该字符串对象的值存入常量池,再返回。

 

 

这里以Openjdk1.8的源码为例,跟下intern方法的底层实现,String.java文件对应的C文件是String.c:

 

JVM_InternString这个方法的定义在jvm.h,实现在jvm.cpp中,在JVM中,Java世界和C++世界的连接层就是jvm.h和jvm.cpp这两文件。

 

可以看出,字符串常量池在JVM内部就是一个HashTable,也就是上面代码中的StringTable。

从 StringTable::intern方法跟下去,可以发现:如果找到了这次操作的字符串,就直接返回found_string;如果没有找到,就将当前的字符串加入到HashTable中,然后再返回。

4. 总结

在Java应用恰当得使用String.intern()方法有助于节省内存空间,但是在使用的时候,也需要注意,因为StringTable的大小是固定的,如果常量池中的字符串过多,会影响程序运行效率。

转载于:https://www.cnblogs.com/hulianwangjiagoushi/p/11010938.html

你可能感兴趣的文章
2015-08-11 [今日头条]--数据抓取和处理工程师--1面
查看>>
1.RT-Thread移植(基于STM32F429IIT6)
查看>>
解决GridView中嵌入CheckBox事件无法响应的问题
查看>>
高压浮动MOS栅极驱动集成电路应用手册
查看>>
转载---数据库优化方案
查看>>
面向对象、函数式
查看>>
微信小程序
查看>>
在线学习重要的是不要停止提问
查看>>
QQ在线客服,默认到要加好友,授权也不起作用需要先开通QQ营销服务
查看>>
pro git
查看>>
UVA 11825 Hackers’ Crackdown(集合动态规划 子集枚举)
查看>>
【转载】初涉职场的40句金玉良言
查看>>
Django使用Mysql数据库已经存在的数据表方法
查看>>
Python-类进阶
查看>>
php函数的参数引用变量
查看>>
统计题量
查看>>
WCF 异步调用问题
查看>>
小白成长之路:初识python(六) --python线程池
查看>>
C#委托的介绍(delegate、Action、Func、predicate)
查看>>
mtk Android 编译命令自定义--添加版本号
查看>>