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 一,前言 本文章是读了“深入理 ...
随机推荐
- git fetch, git pull 剖析
真正理解 git fetch, git pull 要讲清楚git fetch,git pull,必须要附加讲清楚git remote,git merge .远程repo, branch . commi ...
- Servlet--超链接,表单提交,重定向,转发4种情况的路径
实际编码中我们经常写路径,写路径既可以写相对路径,也可以写绝对路径.我2年以前我就养成了习惯,只要是写路径我从来都是写绝对路径,因为万一将来我们的项目的目录发生变化,原来要是写相对路径的话就会有路径依 ...
- 深入分析java传参
概述 java中的参数传递问题可以根据参数的类型大致可以分为三类:传递基本类型,传递String类型,传递引用类型,至于最终是否可以归纳为值传递和引用传递,根据每个人的理解不同,答案不同,此 ...
- DNS入门
引言 常见的计网协议通过IP地址来识别分布式应用的主机,然而IPV4(特别是IPV6)的地址太繁琐难以使用和记忆,因此提出了使用主机名称来识别,实质是:主机名称通过称为名称解析的过程转换为IP地址.其 ...
- ORACLE SQL脚本能否修改字段名称?
在看到标题时,你先想想:在ORACLE中能否修改一个表的某个字段名呢?如果能的话,你是否还记得SQL脚本如何写的呢,呵呵,写这个的目的是因为在论坛上看见许多信誓旦旦的说ORACLE中不能修改字段名称, ...
- CSS——盒模型
1.基本概念: 内容:(content)盒子里面的东西: 填充:(padding)怕盒子里面的东西损坏而添加的泡沫元素活抗震材料: 边框:(border)盒子本身 边界:(margin)则说明盒子的摆 ...
- css正三角倒三角
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- wpf图片浏览器,实现缩放平移操作图片切换等功能
wpf经常要用到控件来查看图片,尤其是高清图片,于是做了一个例子: 1.定义图片的队列,用list来存. private readonly List<string> files; 2.切换 ...
- java 世界中Annotation
java 世界中Annotation 在github上开始汇总一些自己学习,收集,总结,经验的一些信息,有利于跟踪,修改,提升.如果你感兴趣 可以关注一下,也可以提供自己的内容进来. https:// ...
- BZOJ 2565: 最长双回文串 [Manacher]
2565: 最长双回文串 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1842 Solved: 935[Submit][Status][Discu ...