一直很想知道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的一些理解的更多相关文章

  1. 【JVM虚拟机】(7)---深入理解Class中-属性集合

    #[JVM虚拟机](7)---深入理解Class中-属性集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机](6)- ...

  2. 【JVM虚拟机】(8)--深入理解Class中--方法、属性表集合

    #[JVM虚拟机](8)--深入理解Class中--方法.属性表集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机] ...

  3. 【JVM虚拟机】(6)---深入理解Class中访问标志、类索引、父类索引、接口索引

    JVM(6)访问标志,类索引 上一篇博客讲[JVM虚拟机](5)---深入理解JVM-Class中常量池 我们知道一个class文件正常可以分为7个部分: 魔数与class文件版本 常量池 访问标志 ...

  4. 【JVM虚拟机】(5)---深入理解JVM-Class中常量池

    深入理解Class---常量池 一.概念 1.jvm生命周期 启动:当启动一个java程序时,一个jvm实例就诞生了,任何一个拥有main方法的class都可以作为jvm实例运行的起点. 运行:mai ...

  5. WeakHashMap回收时机

    import java.util.ArrayList; import java.util.List; import java.util.WeakHashMap; public class TestWe ...

  6. 深入理解JVM——虚拟机GC

    对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法),通过可达性分析来判定对象是否存活.这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点,从 ...

  7. 深入理解JVM虚拟机6:深入理解JVM类加载机制

    深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...

  8. 学习JVM虚拟机原理总结

    0x00:JAVA虚拟机的前世今生 1991年,在Sun公司工作期间,詹姆斯·高斯林和一群技术人员创建了一个名为Oak的项目,旨在开发运行于虚拟机的编程语言,允许程序多平台上运行.后来,这项工作就演变 ...

  9. JVM虚拟机深入理解+GC回收+类加载

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/81455449 一,前言 本文章是读了“深入理 ...

随机推荐

  1. HSSF、XSSF和SXSSF区别以及Excel导出优化

    之前有写过运用POI的HSSF方式导出数据到Excel(见:springMVC中使用POI方式导出excel至客户端.服务器实例),但这种方式当数据量大到一定程度时容易出现内存溢出等问题. 首先,PO ...

  2. Markdown中使用mermaid画流程图

    Markown语法简单,用来写文档是个不错的选择. 但是Markdown 语法并不直接支持画图,当然方法还是有的. 本人用的Markdown编辑器为vscode,在里面直接安装merdaid插件即可使 ...

  3. PHP中文网上的分页代码

    page.php <html> <head> <meta http-equiv="CONTENT-TYPE" content="text/h ...

  4. python之金融与量化分析

      一.金融 二.ipython 基础功能 ipython 快捷键

  5. 将Session放入Redis

    默认情况下,我们的PHP是以文件的形式保存Session数据,所以,每次读写会话信息,就需要去访问硬盘. 为了解决会话信息夸域名问题,即为了实现同一时刻只能一个地方登录,同时也解决读写会话信息必须访问 ...

  6. ubuntu 新手入门第一天

    在虚拟机上安装好linux之后,当前版本 ubuntu-16.04.3-desktop-amd64.iso 1. 设置root用户名和密码 sudo passwd 然后输入两次密码 2. 设置软件源 ...

  7. FreeMarker template error: The following has evaluated to null or missing: ==> blogger.md [in template "admin/about.ftl" at line 44, column 84]

    FreeMarker template error:The following has evaluated to null or missing:==> blogger.md [in templ ...

  8. Kafka Consumer

    Push VS Pull An initial question we considered is whether consumers should pull data from brokers or ...

  9. java web 获取客户端操作系统信息

    package com.java.basic.pattern; import java.util.regex.Matcher; import java.util.regex.Pattern; /** ...

  10. webrtc底层一对一连接过程探索(二)

    一.连接过程继续解读-----fun32解读 1.1 fun32.02 "undefined" != typeof cordova && (N = !0, D = ...