StringTable---字符串常量池的垃圾回收跟踪案例
引言
很多人认为jvm字符串常量不会被回收的,其实这个说法的有误区的,我们通过一些jvm参数可以看到StringTable的垃圾回收。
案例说明
参数说明
| 参数 | 说明 |
|---|---|
| -Xmx10m | 堆空间大小 |
| -XX+PrintStringTableStatistics | 打印串池统计信息 |
| -XX:+PrintGCDetails | 打印GC日志详情 |
| -verbose:gc | 打印GC日志 |
先来一段空程序,我们使用参数运行:
-Xmx10m -XX+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc
public static void main(String[] args) {
int i=0;
try {
}catch (Throwable e){
e.printStackTrace();
}finally {
System.out.println(i);
}
}
结果如下:
0
Heap
PSYoungGen total 2560K, used 1388K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
eden space 2048K, 67% used [0x00000007bfd00000,0x00000007bfe5b100,0x00000007bff00000)
from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
to space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
ParOldGen total 7168K, used 0K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
object space 7168K, 0% used [0x00000007bf600000,0x00000007bf600000,0x00000007bfd00000)
Metaspace used 2927K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 319K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets : 20011 = 160088 bytes, avg 8.000
Number of entries : 11756 = 282144 bytes, avg 24.000
Number of literals : 11756 = 455312 bytes, avg 38.730
Total footprint : = 897544 bytes
Average bucket size : 0.587
Variance of bucket size : 0.587
Std. dev. of bucket size: 0.766
Maximum bucket size : 6
StringTable statistics:
Number of buckets : 60013 = 480104 bytes, avg 8.000
Number of entries : 831 = 19944 bytes, avg 24.000
Number of literals : 831 = 56304 bytes, avg 67.755
Total footprint : = 556352 bytes
Average bucket size : 0.014
Variance of bucket size : 0.014
Std. dev. of bucket size: 0.118
Maximum bucket size : 2
我们看到程序输出了堆信息,以及串池统计信息,需要了解的是我们的串池实现其实是类似Map的存储结构,里面的存储结构是数组的方式,每一个bucket就是一个数组结构,代表了里面存储的字符串个数。
Number of buckets : 60013 = 480104 bytes, avg 8.000
Number of entries : 831 = 19944 bytes, avg 24.000
Number of literals : 831 = 56304 bytes, avg 67.755
我们假设如下,如果不存在gc,我们写入10万个字符,那么Number of entries 会增加到10万。我们调整程序如下:
int i=0;
try {
for(int j=0;j<100000;j++){
String.valueOf(j).intern();
i++;
}
}catch (Throwable e){
e.printStackTrace();
}finally {
System.out.println(i);
}
运行查看结果:
[GC (Allocation Failure) [PSYoungGen: 2048K->496K(2560K)] 2048K->504K(9728K), 0.0015310 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2544K->512K(2560K)] 2552K->528K(9728K), 0.0010023 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2560K->480K(2560K)] 2576K->520K(9728K), 0.0013527 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
100000
Heap
PSYoungGen total 2560K, used 1295K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
eden space 2048K, 39% used [0x00000007bfd00000,0x00000007bfdcbc60,0x00000007bff00000)
from space 512K, 93% used [0x00000007bff00000,0x00000007bff78020,0x00000007bff80000)
to space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
ParOldGen total 7168K, used 40K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
object space 7168K, 0% used [0x00000007bf600000,0x00000007bf60a000,0x00000007bfd00000)
Metaspace used 3095K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 339K, capacity 388K, committed 512K, reserved 1048576K
SymbolTable statistics:
Number of buckets : 20011 = 160088 bytes, avg 8.000
Number of entries : 12129 = 291096 bytes, avg 24.000
Number of literals : 12129 = 467440 bytes, avg 38.539
Total footprint : = 918624 bytes
Average bucket size : 0.606
Variance of bucket size : 0.606
Std. dev. of bucket size: 0.778
Maximum bucket size : 6
StringTable statistics:
Number of buckets : 60013 = 480104 bytes, avg 8.000
Number of entries : 15285 = 366840 bytes, avg 24.000
Number of literals : 15285 = 866120 bytes, avg 56.665
Total footprint : = 1713064 bytes
Average bucket size : 0.255
Variance of bucket size : 0.267
Std. dev. of bucket size: 0.516
Maximum bucket size : 4
我们发现日志显示发生了三次Yong gc,Number of entries 是15285,没有达到10万,说明了我们的串池是会发生GC的。
StringTable---字符串常量池的垃圾回收跟踪案例的更多相关文章
- JVM字符串常量池StringTable
String的基本特性 String:字符串,使用一对""引起来表示. String sl = "hello"://字面量的定义方式: String s2 = ...
- 8.StringTable(字符串常量池)
一.String的基本特性 String:字符串,使用一对 "" 引起来表示 String s1 = "atguigu" ; // 字面量的定义方式 Strin ...
- 从HotSpot VM源码看字符串常量池(StringTable)和intern()方法
引言 字符串常量池(StringTable)是JVM中一个重要的结构,它有助于避免重复创建相同内容的String对象.那么StringTable是怎么实现的?"把字符串加入到字符串常量池中& ...
- Java String:字符串常量池(转)
作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么? 字符串常量池的设计思想是什么? 字符串常量池在哪里? 如何操作字符串常量 ...
- String:字符串常量池
String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...
- 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...
- Knowledge Point 20180309 字符串常量池与String,intern()
引言 什么都先不说,先看下面这个引入的例子: public static void test4(){ String str1 = new String("SEU") + new S ...
- 深入探究JVM之内存结构及字符串常量池
前言 Java作为一种平台无关性的语言,其主要依靠于Java虚拟机--JVM,我们写好的代码会被编译成class文件,再由JVM进行加载.解析.执行,而JVM有统一的规范,所以我们不需要像C++那样需 ...
- Class常量池、运行时常量池、字符串常量池的一些思考
Class常量池.运行时常量池.字符串常量池 class常量池 java代码经过编译之后都成了xxx.class文件,这是java引以为傲的可移植性的基石.class文件中,在CAFEBABE.主次版 ...
随机推荐
- hive行转列,列转行
实例一:来源: https://www.cnblogs.com/kimbo/p/6208973.html 行转列 (对某列拆分,一列拆多行) 使用函数:lateral view explode(spl ...
- 首秀:Markdown学习笔记
# Markdown学习 ## 标题 ### 三级标题 #### 四级标题 ## 字体 **Hello,World!** *Hello,World!* ***Hello,World!*** ~~Hel ...
- 【排序】题解_P1093奖学金
题目描述 奖学金 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生都有3门课的成绩:语文.数学.英语.先按总分从高到低排序,如果两个同学总分相同,再按语文 ...
- 【Java基础】Java8 新特性
Java8 新特性 Lambda 表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).使用它可以写出更简洁.更灵活的代码. L ...
- 【JavaWeb】Cookie&Session
Cookie&Session Cookie 什么是 Cookie Cookie 即饼干的意思 Cookie 是服务器通知客户端保存键值对的一种技术 客户端有了 Cookie 后,每次请求都发送 ...
- paramunittest参数化测试基础
samples: import paramunittestimport unittest@paramunittest.parametrized( (10,20), (30,40), # (100,20 ...
- 为了加快速度,Redis都做了哪些“变态”设计
前言 列表对象是 Redis 中 5 种基础数据类型之一,在 Redis 3.2 版本之前,列表对象底层存储结构有两种:linkedlist(双端列表)和 ziplist(压缩列表),而在 Redis ...
- linux硬盘分区和fdisk命令
分区的几个概念 硬盘分区有三种,主分区.扩展分区.逻辑分区.一个硬盘主分区至少有1个,最多4个,扩展分区可以没有,最多1个.且主分区+扩展分区总共不能超过4个.逻辑分区可以有若干个.在windows下 ...
- Oracle 索引原理分析
索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是一个独立于表的对象,可以存放在与表不同的表空间中.索引记录中存有索引关键字和指向表中数据的指针(地址).对索引进行的I/O ...
- Centos6.9安装ACFS
安装完oracle 11GR2的RAC后,使用asmca打开图形化界面后,发现Volumes和ASM Cluster File System两个选项卡不能用 原因是因为ACFS不支持CentOS 解决 ...