StringTable垃圾回收问题StringTable会自动进行垃圾回收 , 这也是我们在JDK运行中选择StringTable的原因之一
我们通过一个简单的案例进行解释:
package cn.itcast.jvm.t1.stringtable;import java.util.ArrayList;import java.util.List;/** * 演示 StringTable 垃圾回收 * -Xmx10m -XX:+PrintStringTableStatistics(打印StringTable内容) -XX:+PrintGCDetails -verbose:gc(打印垃圾回收) */public class Demo1_7 {public static void main(String[] args) throws InterruptedException {int i = 0;try {for (int j = 0; j < 100000; j++) { // 设置1w个数// 这里如果不采用.intern()// 我们会发现1w个数全部存入内存中String.valueOf(j);i++;}} catch (Throwable e) {e.printStackTrace();} finally {System.out.println(i);}}}/** * 演示 StringTable 垃圾回收 * -Xmx10m -XX:+PrintStringTableStatistics(打印StringTable内容) -XX:+PrintGCDetails -verbose:gc(打印垃圾回收) */public class Demo1_7 {public static void main(String[] args) throws InterruptedException {int i = 0;try {for (int j = 0; j < 100000; j++) { // 设置1w个数// 这里如果采用.intern()// 我们会发现StringTable里面的值会少于1w , 这是因为发生了垃圾回收 , 回收掉不使用的信息String.valueOf(j).intern();i++;}} catch (Throwable e) {e.printStackTrace();} finally {System.out.println(i);}}}
StringTable调优最后我们介绍StringTable的调优方法:
- 设置桶的个数
// 我们直到StringTable是一个哈希表,哈希表里面桶的个数会影响其效率// 如果桶过少,每个桶存储信息过多导致查找缓慢;如果桶过多,导致信息分布较为疏散导致查找缓慢// 我们提供一个配置来改变桶的个数:-XX:StringTableSize=10000(需要设计恰到好处的桶个数)package cn.itcast.jvm.t1.stringtable;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;/** * 演示串池大小对性能的影响 * -Xms500m -Xmx500m -XX:+PrintStringTableStatistics -XX:StringTableSize=1009 */public class Demo1_24 {public static void main(String[] args) throws IOException {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if (line == null) {break;}line.intern();}System.out.println("cost:" + (System.nanoTime() - start) / 1000000);}}}
- 考虑字符串对象是否入池
// 我们同样可以采用intern来判断该字符串是否应该入池// 我们排除掉相同的字符串自然可以节省空间~package cn.itcast.jvm.t1.stringtable;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;/** * 演示 intern 减少内存占用 * -XX:StringTableSize=200000 -XX:+PrintStringTableStatistics * -Xsx500m -Xmx500m -XX:+PrintStringTableStatistics -XX:StringTableSize=200000 */public class Demo1_25 {public static void main(String[] args) throws IOException {List<String> address = new ArrayList<>();System.in.read();for (int i = 0; i < 10; i++) {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if(line == null) {break;}// 如果这里不采用.tern会导致全部字符串进入,导致储存较多address.add(line);}System.out.println("cost:" +(System.nanoTime()-start)/1000000);}}System.in.read();}}/** * 演示 intern 减少内存占用 * -XX:StringTableSize=200000 -XX:+PrintStringTableStatistics * -Xsx500m -Xmx500m -XX:+PrintStringTableStatistics -XX:StringTableSize=200000 */public class Demo1_25 {public static void main(String[] args) throws IOException {List<String> address = new ArrayList<>();System.in.read();for (int i = 0; i < 10; i++) {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if(line == null) {break;}// 如果这里采用.tern就会筛选字符串,来进行调优~address.add(line.tern());}System.out.println("cost:" +(System.nanoTime()-start)/1000000);}}System.in.read();}}
直接内存这小节我们来介绍系统中常用的直接内存直接内存简介我们先来介绍一下直接内存的定义:
- 直接内存不受JVM内存回收管理
- 直接内存是直接受管于系统的内存,不能被JVM所调配
- 直接内存通常用于NIO操作 , 用于数据缓冲区,其分配成本较高,但读写性能较高
package cn.itcast.jvm.t1.direct;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;/** * 演示 ByteBuffer 作用 */public class Demo1_9 {static final String FROM = "E:\\编程资料\\第三方教学视频\\youtube\\Getting Started with Spring Boot-sbPSjI4tt10.mp4";static final String TO = "E:\\a.mp4";static final int _1Mb = 1024 * 1024;public static void main(String[] args) {io(); // io 用时:1535.586957 1766.963399 1359.240226directBuffer(); // directBuffer 用时:479.295165 702.291454 562.56592}// directBuffer(直接内存读取数据)private static void directBuffer() {long start = System.nanoTime();try (FileChannel from = new FileInputStream(FROM).getChannel();FileChannel to = new FileOutputStream(TO).getChannel();) {ByteBuffer bb = ByteBuffer.allocateDirect(_1Mb);while (true) {int len = from.read(bb);if (len == -1) {break;}bb.flip();to.write(bb);bb.clear();}} catch (IOException e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("directBuffer 用时:" + (end - start) / 1000_000.0);}// io(jvm正常读取数据)private static void io() {long start = System.nanoTime();try (FileInputStream from = new FileInputStream(FROM);FileOutputStream to = new FileOutputStream(TO);) {byte[] buf = new byte[_1Mb];while (true) {int len = from.read(buf);if (len == -1) {break;}to.write(buf, 0, len);}} catch (IOException e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("io 用时:" + (end - start) / 1000_000.0);}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 【lwip】08-ARP协议一图笔记及源码实现
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis
- Nacos基本学习
- 数据科学学习手札146 geopandas中拓扑非法问题的发现、诊断与修复