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.主次版 ...
随机推荐
- [ABP教程]第二章 图书列表页面
Web应用程序开发教程 - 第二章: 图书列表页面 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开 ...
- 【对线面试官】Java NIO
服务端: public class NoBlockServer { public static void main(String[] args) throws IOException { // 1.获 ...
- flask socketio 踩坑记录
在使用python3的flask-socketio+socket.io.js的时候报错 在使用python3的flask-socketio+socket.io.js的时候报错"unsuppo ...
- IE浏览器F12无法使用
原文链接http://zhhll.icu/2020/04/07/windows/IE%E6%B5%8F%E8%A7%88%E5%99%A8F12%E6%97%A0%E6%B3%95%E4%BD%BF% ...
- Jenkins-自动部署,备份
Jenkins-自动部署,备份 问题导入: 环境: CentOS 7, Tomcat 8.5, Jdk 1.8, Maven 3.25 ,Jenkins war包 2.x 原因: 每次部署 ...
- kubernetes环境部署单节点redis
kubernetes部署redis数据库(单节点) redis简介 Redis 是我们常用的非关系型数据库,在项目开发.测试.部署到生成环境时,经常需要部署一套 Redis 来对数据进行缓存.这里介绍 ...
- PAT天梯赛练习 L3-004 肿瘤诊断 (30分) 三维BFS
题目分析: 可能是我的理解能力比较差,在读题的时候一直以为所有的切片是可以排列组合的,并不是按照输入顺序就定死的,那么这题就变得十分的复杂啦~~~~~,查看的题解之后发现所有的切片并没有所谓的自由组合 ...
- Linux Bash Shell常用快捷键
Linux Bash Shell常用快捷键 table { margin: auto } 快捷键 功能 tab 补全 ctrl + a 光标回到命令行首 ctrl + e 光标回到命令行尾 ctrl ...
- Docker学习笔记之使用Docker数据卷
Docker数据卷将数据存储到主机而非容器,多个容器需要共享数据时,常常使用数据卷. 1. 为容器设置数据卷(不指定主机目录) 2. 容器与主机之间.容器与容器之间共享数据卷(指定主机目录) 3. 使 ...
- 【Oracle】查看表或视图的创建语句
这里用到的是Oracle的DDL语句的用法 用于获得某个schema下所有的表.索引.视图.存储过程.函数的DDL set pagesize 0 set long 90000 set feedback ...