第十一天实战篇

目录

一、redis缓存数据如何更新?

二、GCC回收对象

三、jvm中对象和对象名存储的位置?

四、缓存失效的三种场景


1、缓存失效策略:
当需要更新缓存数据时,可以先使缓存数据失效,然后等待下一次查询时重新从数据库中加载数据并重新缓存。
这种策略的优点是简单易行,但是可能会导致缓存击穿的问题,即在缓存失效的瞬间,有
大量的并发请求同时访问数据库,导致数据库压力过大,可以通过加锁保证线程安全性解决。

2、更新缓存策略:
当需要更新缓存数据时,可以先更新数据库中的数据,然后再更新缓存中的数据。
这种策略的优点是可以保证缓存数据的实时性,但是需要考虑并发更新的问题。
高并发场景下,可能会出现多个线程同时更新缓存数据的情况,导致数据的不一致性。
为了避免这种情况,可以使用分布式锁来保证同一时间只有一个线程可以更新缓存数据。

二、GCC回收对象

gcc如果要回收堆内存中的对象的时候是一定会回收吗?

不是,因为当程序运行时,操作系统会为程序分配一定的内存空间
其中包括堆内存,程序可以在堆内存中分配和释放内存。当程序结束时,
操作系统会回收所有分配的内存空间,包括堆内存。
但是,如果程序中存在内存泄漏或者指针未正确删除的情况,那么这部分内存将无法被回收,从而导致内存泄漏


三、jvm中对象和对象名存储的位置?

jvm中,对象名是存在栈内存中,在Java虚拟机(JVM)中,
对象名是存储在堆内存中的,而不是存储在JVM中的某个特定位置。
当创建一个对象时,JVM会在堆内存中为该对象分配一块内存空间,
该空间的大小取决于对象的类型和实例变量的数量。
然后,JVM会用该对象的引用来指向该内存空间,使得程序可以访问该对象及其实例变量。
在Java中,对象的引用是一个指向对象内存地址的指针,该指针存储在栈内存中。
因此,可以说对象名是存储在栈内存中的,而对象本身是存储在堆内存中的。

总之:对象名存在栈内存,对象的引用是一个指向内存地址的指针,改指针存在栈内存中,指针指向堆内存中的对象


四、缓存失效的三种场景

缓存穿透:
1、一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。
一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力,
这就叫做缓存穿透。
如何避免?
1.对查询结果为null的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2.对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩:

高并发下大量请求进来查询一个海量数据key设置了相同的过期时间
或者缓存服务器重启会导致海量相同时间的key失效,导致缓存失效,大量请求到数据库,
解决缓存雪崩
2.1、不同的key设置不同的过期时间,让缓存失效的时间尽量均匀
2.2、做二级缓存

缓存击穿:

高并发访问热点的key,导致缓存击穿,可以通过加锁解决。

你可能感兴趣的:(jvm,java,缓存)