面试题答案
一键面试内存占用方面
- intern方法作用:
intern
方法会将字符串对象放入字符串常量池(在JDK 7及之后,字符串常量池在堆中)。如果常量池中已经存在该字符串,则返回常量池中的引用;否则,将该字符串对象的引用放入常量池并返回。 - 对内存的影响:在高并发项目中,大量固定字符串常量使用
intern
方法,若这些字符串之前未在常量池,会增加常量池的内存占用。但从整体堆内存角度看,由于多个地方可复用常量池中的字符串,能减少堆中字符串对象的重复创建,在一定程度上可能降低堆内存使用。例如有1000个线程都要使用'PAID'字符串,如果都创建新对象会占用较多堆内存,使用intern
后常量池只需一份'PAID'字符串。
字符串比较效率方面
- 比较原理:使用
==
比较两个通过intern
方法得到的字符串,比较的是对象引用,效率很高。因为常量池中的字符串是唯一的,只要引用相同则字符串内容相同。而使用equals
方法比较字符串,需要逐个字符比对内容,效率相对较低。 - 对效率的提升:在高并发场景下,经常进行字符串比较操作时,使用
intern
方法后用==
比较能大大提高比较效率。比如在订单状态判断逻辑中频繁比较订单状态字符串,intern
后用==
可加快判断速度。
可能存在的风险
- 性能风险:调用
intern
方法本身有一定性能开销,特别是在高并发情况下,如果每次都调用intern
,可能导致性能瓶颈。因为在常量池中查找字符串是否存在并进行相应操作需要时间。 - 内存溢出风险:如果大量不同的字符串都调用
intern
方法,可能导致字符串常量池内存溢出。例如在一些恶意攻击场景下,攻击者不断发送不同的字符串使常量池不断膨胀。
避免风险的方法
- 减少不必要的intern调用:只对确实会被大量复用且固定不变的字符串调用
intern
方法,对于一些临时的、不重复使用的字符串无需调用。 - 监控与限制:通过JVM监控工具监控字符串常量池的使用情况,设置合理的常量池大小参数(如
-XX:StringTableSize
)。同时在代码层面,对于可能来自外部不可信输入的字符串,避免直接调用intern
,防止恶意攻击导致常量池溢出。