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.主次版 ...
随机推荐
- codeforces 1451D,一道有趣的博弈论问题
大家好,欢迎来到codeforces专题. 今天选择的问题是Contest 1451场的D题,这是一道有趣简单的伪博弈论问题,全场通过的人有3203人.难度不太高,依旧以思维为主,坑不多,非常友好. ...
- go语言实现99乘法表
Go语言学习笔记(99乘法表)-day01 通过for循环实现99乘法表 预期效果 源代码 for x :=1;x<10;x++{ for y :=1;x>=y;y++{ fmt.Prin ...
- vs code编写java
不知不觉中vs code变得非常强大了,今天小编就分享一下vs code编写java语言.其实除了java语言,还支持很多语言. 首先看下vs code欢迎页面支持哪些语言: 好家伙,支持的东西还真不 ...
- FastAPI学习: 个人博客的后端API
前言 学习FastAPI中把官方文档过了一遍,看了些大佬的文章,也借鉴(抄袭)了部分代码,写了一套个人博客的API,目前还比较简陋,统计的API基本没有,而且目前基本都停留在单表查询,所以含量不高,接 ...
- .netcore 急速接入第三方登录,不看后悔
新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢. 如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下: https://oauthlogin.net/ 前言 此次带来得这个小 ...
- TCP/IP五层模型-传输层-TCP协议
1.定义:TCP是一种面向连接.可靠的.基于字节流的传输控制协议. 2.应用场景:TCP为可靠传输,适合对数据完整性要求高,对延时不敏感的场景,比如邮件. 3.TCP报文:①TCP报文格式: ②TC ...
- SAP中数据库表长度的界定
SAP中,如何查看表和关键字的长度?通过SE11菜单栏Extras->table width 可以看到.然而SAP在系统也会将表分类,特别是在可扩展的表维护视图中,分为如下几类 ult ...
- 关于springboot项目通过jar包启动之后无法读取项目根路径静态资源
在一次项目开发过程中,项目根路径下存放了一张图片,生成二维码的时候调用了该图片作为二维码的logo,在windows环境下二维码可以正常生成,但是部署到生产测试环境之后二维码生成报错,FileNotF ...
- python_mmdt:从0到1--实现简单恶意代码分类器(二)
概述 上篇文章python_mmdt:一种基于敏感哈希生成特征向量的python库(一)我们介绍了一种叫mmdt_hash(敏感哈希)生成方法,并对其中的概念做了基本介绍.本篇,我们重点谈谈mmdt_ ...
- 记录list.remove()和list.pop()
list.remove(obj):这个是移除列表中某个值的第一个匹配项 list.pop(index):这个是移除列表中下标为index的元素 当元素全是数字或者有数字时注意区分.