阿里面试官:字符串在JVM中如何存放?90%的人就真的只回答在哪里存放

目录:

  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

时间: 2024-11-05 20:40:31

阿里面试官:字符串在JVM中如何存放?90%的人就真的只回答在哪里存放的相关文章

面试官,Java8 JVM内存结构变了,永久代到元空间

在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试者,如果知晓这些变化,又将成为面试中的亮点. 如果在网络上搜索JVM内存结构,90%的可能会搜到Java7及以前的内存图,本篇文章将会对JVM内存结构再次细化,深入理解Java8之后的内部变化.现在意识到关注公众号"程序新视界"的好处了吧.在这里可以不断的刷新你的知识和认知. JV

当面试官说 &ldquo;你还有什么问题想问的&rdquo; ,你该如何回答?

阅读本文大概需要 4 分钟. 作者:黄小斜 来源:程序员江湖 程序员面试时经常会听到面试官说一些套话,比如"今天的面试就到这里了,回去等通知吧","你还有什么问题想问我的吗","如果这道题不会做,那么我们也可以换一道" 今天我们要说的是大多数面试官都会说的一句话"你还有什么问题想问的?" 这是一个老生常谈的问题,之前经历过不少面试,针对这个问题我也做过很多不同的回答,当然也参考了其他人的一些建议,我这里总结了几种回答的方法,仅

【真实面试经历】我和阿里面试官的一次“邂逅”(附问题详解)

本文的内容都是根据读者投稿的真实面试经历改编而来,首次尝试这种风格的文章,花了几天晚上才总算写完,希望对你有帮助. 本文主要涵盖下面的内容: 分布式商城系统:架构图讲解: 消息队列相关:削峰和解耦: Redis 相关:缓存穿透问题的解决: 一些基础问题: 网络相关:1.浏览器输入 URL 发生了什么? 2.TCP 和 UDP 区别? 3.TCP 如何保证传输可靠性? Java 基础:1. 既然有了字节流,为什么还要有字符流? 2.深拷贝 和 浅拷贝有啥区别呢? 下面是正文! 面试开始,坐在我前面

阿里面试官让我讲讲Unicode,我讲了3秒说没了,面试官说你可真菜

本文首发于微信公众号:程序员乔戈里 乔哥:首先说说什么是Unicode.码点吧~要想搞懂,这些概念必须清楚 什么是Unicode? 下图来自http://www.unicode.org/standard/WhatIsUnicode.html中的截图 Unicode编码定义了这个世界上几乎所有字符(就是你眼睛看的字符比如ABC,汉字等)的数字表示,而且Unicode还兼容了很多老版本的编码规范,例如你熟悉的 ASCII码. 什么是码点? 我们国家的每一个人都对应唯一的一个身份证号,而Unicode

面试官问我“Java中的锁有哪些?以及区别”,我跪了

在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 上面是很多锁的名词,这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计,下面总结的内容是对每个锁的名词进行一定的解释. 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁.非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线

【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看

不是线程的安全 面试官问:"什么是线程安全",如果你不能很好的回答,那就请往下看吧. 论语中有句话叫"学而优则仕",相信很多人都觉得是"学习好了可以做官".然而,这样理解却是错的.切记望文生义. 同理,"线程安全"也不是指线程的安全,而是指内存的安全.为什么如此说呢?这和操作系统有关. 目前主流操作系统都是多任务的,即多个进程同时运行.为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程的,这是由操作系统保障

面试官,Java8中JVM内存结构变了,永久代到元空间

在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试者,如果知晓这些变化,又将成为面试中的亮点. 如果在网络上搜索JVM内存结构,90%的可能会搜到Java7及以前的内存图,本篇文章将会对JVM内存结构再次细化,深入理解Java8之后的内部变化.现在意×××"的好处了吧.在这里可以不断的刷新你的知识和认知. JVM内存结构的细化 来看一下JVM中的内存结构图. 为了更细化的讲解,我们将该图进行进一步的优化调整.针对java7及以

我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration

现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法.一行简单的注解就可以解决很多事情.但是,其实每一个注解背后都有很多值得学习和思考的内容.这些思考的点也是很多大厂面试官喜欢问的内容. 在一次关于Spring注解的面试中,可能会经历面试官的一段夺命连环问: @Configuration有什么用?br/>@Configuration和XML有什么区别?哪种好?Spring是如何基于来获取Bean的定义的?@Autowired . @Inject.

我以为我对Mysql索引很了解,直到我遇到了阿里的面试官(转)

本文来自一位不愿意透露姓名的粉丝投稿 相信很多人对于MySQL的索引都不陌生,索引(Index)是帮助MySQL高效获取数据的数据结构. 因为索引是MySQL中比较重点的知识,相信很多人都有一定的了解,尤其是在面试中出现的频率特别高.楼主自认为自己对MySQL的索引相关知识有很多了解,而且因为最近在找工作面试,所以单独复习了很多关于索引的知识. 但是,我还是图样图森破,直到我被阿里的面试官虐过之后我才知道,自己在索引方面的知识,只是个小学生水平. 以下,是我总结的一次阿里面试中关于索引有关的问题