WeakHashMap回收时机结合JVM 虚拟机GC的一些理解
一直很想知道WeakHashMap的使用场景,想来想去只能用在高速缓存中,而且缓存的数据还不是特别重要,因为key(key不存在被引用的时候)随时会被回收
所以研究了一下WeakHashMap的回收时机
呵呵,现在可以重视 String str = "abc" 跟 String Str = new String("abc") 的区别了,因为涉及到收回问题
String str = "abc" //这属于编译时生成的字面量,会放入运行时常量池,这个区域的收回条件非常苛刻,所以一般不会被回收,所以哪怕不存在引用,WeakHashMap的这个key也不容易被回收
String Str = new String("abc") //会放入堆内存,GC着重处理这个区
/**
*
* @author ZhenWeiLai
*
*/
public class TestWeakHashMap { static WeakHashMap<String,String> map = new WeakHashMap<>();
//会被回收因为 map 的 key 用 new String 实例化了一个对象 保存在堆里,虽然是线程共享,但是并没有任何引用指向这个key
/**
* 这里补充一下,Java heap 是被所有线程共享的一块内存区域
* 几乎所有的对象实例都在这里分配内存,这里说几乎,是因为随着JIT编译器的发展与逃逸分析技术逐渐成熟
* 栈上分配,标量替换等优化技术将导致一些微妙的变化发生,所有的对象都分配在堆上也渐渐变得不是那么绝对
*/
static {
map.put(new String("a"),new String("abc"));
map.put(new String("b"),new String("abc"));
map.put(new String("c"),new String("abc"));
map.put(new String("d"),new String("abc"));
map.put(new String("e"),new String("abc"));
map.put(new String("f"),new String("abc"));
map.put(new String("g"),new String("abc"));
} //会被回收
static WeakHashMap<String,String> map4 = new WeakHashMap<>();
static {
map4.put(new String("a"),"abc");
map4.put(new String("b"),"abc");
map4.put(new String("c"),"abc");
map4.put(new String("d"),"abc");
map4.put(new String("e"),"abc");
map4.put(new String("f"),"abc");
map4.put(new String("g"),"abc");
} static WeakHashMap<String,String> map2 = new WeakHashMap<>();
//不会被收回,因为存在 方法区(以前也叫永久代,JAVA8已经不存在永久代) - 常量池
/**
* (Method Area 别名 Non-Heap) 与Java Heap 一样,是各个线程共享的内存区域,
* 以前这个区域也叫作 永久代,因为几乎不会被回收
* 它用于存储已被虚拟机加载的类信息,常量,静态变量.即时编译后的代码等数据
*/
/**
* map2的key 是存在 运行时常量池,运行时常量池是 Method Area的一部分
* Java并不要求常量一定只有在编译期才能产生,运行期间也可能将新的常量放入池中,具有代表性的就是String的intern()方法
*/
static {
map2.put("a","abc");
map2.put("b","abc");
map2.put("c","abc");
map2.put("d","abc");
map2.put("e","abc");
map2.put("f","abc");
map2.put("g","abc");
} public static void main(String[] args) throws InterruptedException {
while(true){
/**
* 解开注释,map,map4的key将不会被回收
* 我理解为,在栈(也叫线程私有栈,或者工作内存)中,每个线程会将共享数据拷贝到栈顶进行运算,
* 这份数据其实是一个副本.(如果栈内部所包含的"局部变量"是引用,则仅仅是引用值在栈中,而且会占用一个引用本身的大小,具体的对象还是在堆当中,即对象本身的大小与栈空间的使用无关)
* 所以这个map存在一个引用,就不会去回收它的key
*/
// System.out.println("map:"+map.size());
// System.out.println("map2:"+map2.size());
// System.out.println("map4:"+map4.size()); //模拟被一个线程调用,然后休眠5秒,会随机被回收
new Thread(()->{
System.out.println("map:"+map.size());
System.out.println("map2:"+map2.size());
System.out.println("map4:"+map4.size());
System.out.println("-------------------");
}).start();
TimeUnit.SECONDS.sleep(5);
}
}
}
WeakHashMap回收时机结合JVM 虚拟机GC的一些理解的更多相关文章
- 【JVM虚拟机】(7)---深入理解Class中-属性集合
#[JVM虚拟机](7)---深入理解Class中-属性集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机](6)- ...
- 【JVM虚拟机】(8)--深入理解Class中--方法、属性表集合
#[JVM虚拟机](8)--深入理解Class中--方法.属性表集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机] ...
- 【JVM虚拟机】(6)---深入理解Class中访问标志、类索引、父类索引、接口索引
JVM(6)访问标志,类索引 上一篇博客讲[JVM虚拟机](5)---深入理解JVM-Class中常量池 我们知道一个class文件正常可以分为7个部分: 魔数与class文件版本 常量池 访问标志 ...
- 【JVM虚拟机】(5)---深入理解JVM-Class中常量池
深入理解Class---常量池 一.概念 1.jvm生命周期 启动:当启动一个java程序时,一个jvm实例就诞生了,任何一个拥有main方法的class都可以作为jvm实例运行的起点. 运行:mai ...
- WeakHashMap回收时机
import java.util.ArrayList; import java.util.List; import java.util.WeakHashMap; public class TestWe ...
- 深入理解JVM——虚拟机GC
对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活.这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从 ...
- 深入理解JVM虚拟机6:深入理解JVM类加载机制
深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...
- 学习JVM虚拟机原理总结
0x00:JAVA虚拟机的前世今生 1991年,在Sun公司工作期间,詹姆斯·高斯林和一群技术人员创建了一个名为Oak的项目,旨在开发运行于虚拟机的编程语言,允许程序多平台上运行.后来,这项工作就演变 ...
- JVM虚拟机深入理解+GC回收+类加载
旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/81455449 一,前言 本文章是读了“深入理 ...
随机推荐
- SQL SERVER 表最小行的一个纠结问题
昨天一个同事突然问我,说他在SQL 2000数据库创建如下表的时候,突然碰到了下面一条警告信息.SQL脚本和警告信息如下: IF OBJECT_ID(N'Log') IS NULL BEGINCRE ...
- msyql多软件连接
菜鸟一枚 使用mysql删除数据库时,习惯性使用navicat,由于使用的是sqlyog备份的,就用sqlyog恢复数据库,结果总是报错. 用同事电脑没有问题,后来发现是用了不同的软件,导致数据库数据 ...
- 【转】linux下设置ssh无密码登录
ssh配置 主机A:10.0.5.199 主机B:10.0.5.198 需要配置主机A无密码登录主机A,主机B 先确保所有主机的防火墙处于关闭状态. 在主机A上执行如下: 1. $cd ~/.ssh ...
- TCP/IP详解 卷1 第二十一章 TCP的超时与重传
21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1) ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行 ...
- linux服务器配置pyspark解决py4j报错等问题
1.下载spark,python包 略 2.环境变量配置 打开 ~/.bashrc配置文件 如图添加下列环境变量及path 3.退出配置文件,输入 source ~/.bashrc 来执行你添加的一些 ...
- python selenium+phantomjs alert()弹窗报错
问题:用selenium+phantomjs 模拟登陆,网页用JavaScript的alert("登陆成功")弹出框,但是用switch_to_alert().accept()报错 ...
- 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端
接上文 多线程编程学习笔记——使用异步IO 二. 编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...
- 突然觉得前端js挺不错的
由于工作的需要,现在对前端技术有一定的要求,但是发现普遍前端技术都比较弱,遇到问题基本上没有人能帮助你解决,只好自己学习了. 从事java开发已经好久了,真的是好久了,但是水平一直还是一般吧. 从今天 ...
- Spring源码情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory 前文提到最关键的地方是解析bea ...
- BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]
以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...