深入理解Java String#intern() 内存模型
大家知道,Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,就会在字符串常量池中创建该字符串然后再返回。
字符串常量池是一个固定大小的HashMap,桶的数量默认是1009, 从Java7u40开始,该默认值增大到60013。在Java6当中,字符串常量池是放在Perm空间的,从Java7开始,字符串常量池被移到Heap空间。下面,我们通过测试程序来窥探字符串常量池在Java6,Java7两个不同版本底下的内存分配情况。
测试程序
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class StringPoolTest { public void testStringPoolWithLongString(){ long i=0; while(true){ String longString = "This is a very long string, very very long string to test the gc behavior of the string constant pool"+i; longString.intern(); i++; } } public static void main(String[] args){ StringPoolTest stringPoolTest = new StringPoolTest(); stringPoolTest.testStringPoolWithLongString(); }} |
测试程序很简单,一个死循环,循环里面通过递增变量i制造唯一的字符串,然后用main函数启动程序。
Java 6
我们使用版本Jdk1.6.0_29来跑该程序,打开Java VisualVM监控,可以看到,Perm区不断发生GC,由此的出结论,虽然字符串常量池放在Perm空间,但当Perm空间接近满的时候,JVM会将字符串常量池中的无用字符串回收掉。

Java 7
下面,我们切换到Jdk1.7.0_67重跑该程序,可以看到Perm区内存分配曲线很平滑,没有出现内存分配的现象。

但在Heap空间,新的对象不断产生,然后不断触发GC

结论
由于Perm区大小是有限的,通常只有几十MB,所以不推荐在Java6下广泛使用String.intern(),这篇文章string-intern-in-java-6-7-8的性能测试表明,在Java6底下大量使用intern()会导致应用性能的显著下降,还有可能产生OOM错误。但从Java7开始,字符串常量池被移到了Heap空间,Heap空间的大小只受制于机器的真实内存大小,因此,在Java7下使用String.intern()能更有效地减少重复String对象对内存的占用。
深入理解Java String#intern() 内存模型的更多相关文章
- 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)
目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...
- 通过反编译深入理解Java String及intern(转)
通过反编译深入理解Java String及intern 原文传送门:http://www.cnblogs.com/paddix/p/5326863.html 一.字符串问题 字符串在我们平时的编码工作 ...
- String的内存模型,为什么String被设计成不可变的
String是Java中最常用的类,是不可变的(Immutable), 那么String是如何实现Immutable呢,String为什么要设计成不可变呢? 前言 关于String,收集一波基础,来源 ...
- 深入理解JVM(一)——JVM内存模型
JVM内存模型 Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: 1. 程序计数器 2. Java虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区. ...
- java虚拟机的内存模型
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...
- 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型
一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...
- Java对象的内存模型(一)
前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...
- Java虚拟机:内存模型详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...
- 深入理解java String 及intern
一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会 ...
随机推荐
- TFS客户端登录用户修改
1.操作环境: Windows 10 Pro Visual Studio 2013 TFS客户端 2.操作背景 安装完成TFS系统后,使用administrator在客户端进行登陆测试(已勾选保存用户 ...
- 阿里云搭建LAMP环境详细教程
一.云服务器的选择 随着大数据时代的到来,为了满足更为复杂的运算和用户更为苛刻的需求,云计算应运而生,随之而来的就是云服务器.过去的服务器成本较高,运算模式较为单一,资源利用率不高,而云服务器的出现刚 ...
- ODCA最佳实践翻译:Architecting Cloud-Aware Applications (一)
Architecting Cloud-Aware Applications ** ODCA(Open Data Center Alliance)最佳实践 ** MagicBowen(e.bowen.w ...
- Oracle 事务
begin begin savepoint p1; DELETE FROM sys_re_xxx; //红色部分替换为需要一起执行的SQL即可 DELETE FROM SYS_xxxx; ...... ...
- socket学习笔记——IO口的基本操作(读、写)
写操作 1 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unist ...
- iOS 如何根据经纬度来定位位置
/** * 初始化一个经纬度结构体 */ CLLocationCoordinate2D center = {[latitudeTF.text floatValue],[longitudeTF.tex ...
- Leetcode001 two sum
/* c++ STL is much nore than what i think before in these aspects: * initializer for node element in ...
- SVN 忽略获取和提交obj、bin文件夹
一.全局设置的方式(貌似不行) SVN忽略文件夹刚开始用的是这种方式: Settings => Subversion里的Global ignore pattern增加这两项*/bin */obj ...
- 【MySQL】TokuDB引擎初探(MySQL升级为Percona,MySQL升级为MariaDB)
参考:http://blog.sina.com.cn/s/blog_4673e6030102v46l.html 参考:http://hcymysql.blog.51cto.com/5223301/14 ...
- 使用c#数据库连接池
摘自: http://www.wxphp.com/wxd_0fetn2bw2548fsc2ak8h_1.html 导读:使用C#数据库连接池,连接到数据库服务器通常由几个需要软长时间的步骤组成,必须与 ...