永久代一般存储类的信息,用的类越多,永久代越满。永久代在项目开始时就固定大小,项目运行功能越久,gc越难。
metaspace存储在本地内存中,不在java虚拟机中。可以支持很大的开销16g。
在Java代码中,Class的加载、连接与初始化过程都是在程序运行期间完成的。
gcroot有哪些?
垃圾回收算法主要有四个
GC(Garbage Collection)垃圾回收器是Java虚拟机(JVM)中的一种内存管理机制,用于自动回收不再使用的对象,释放其占用的内存空间。GC垃圾回收器通常分为串行垃圾回收器、并行垃圾回收器、并发垃圾回收器、G1垃圾回收器等几种。
串行垃圾回收器:串行垃圾回收器是最简单的垃圾回收器,它只使用一个线程进行垃圾回收操作。适合单CPU环境下的小型应用程序。
并行垃圾回收器:并行垃圾回收器使用多个线程进行垃圾回收操作,提高了垃圾回收的效率,但会增加系统的负载。适合多CPU环境下的中型应用程序。
并发垃圾回收器:并发垃圾回收器在应用程序运行的同时进行垃圾回收操作,减少了GC停顿时间,但也会增加系统的负载。适合大型应用程序。
G1垃圾回收器:G1垃圾回收器是一种面向服务器的垃圾回收器,它将堆内存分为多个小块进行回收,可以在不同区域之间进行动态调整,从而提高了垃圾回收的效率和吞吐量,减少了GC停顿时间。
选择哪种垃圾回收器需要根据应用程序的特点、硬件配置和性能要求等因素来确定。在实际应用中,可以通过调整JVM参数来选择垃圾回收器类型和优化垃圾回收器性能。
线上GC频繁问题通常是由于内存占用过高而导致的,可以采取以下几种方法来解决:
调整JVM参数:通过调整JVM参数,如-Xms、-Xmx、-XX:NewSize、-XX:MaxNewSize、-XX:SurvivorRatio等,可以减少GC的频率和时间。具体的参数调整需要根据应用程序的内存使用情况和服务器硬件配置等因素来确定。
优化代码:尽量避免创建大量临时对象,使用对象池或重用对象等方式减少内存使用。避免使用大量的String操作和字符串连接,使用StringBuilder或StringBuffer等方式代替。避免使用大量的finalize方法,可以手动释放资源等。
使用缓存:将一些经常使用的数据缓存在内存中,减少频繁的查询和计算,可以使用缓存框架如Redis、Memcached等。
增加服务器内存:增加服务器内存可以减少GC的频率和时间,提高应用程序的性能。
使用分布式架构:使用分布式架构可以将应用程序分布在多个服务器上,减少单个服务器的负载,从而减少GC的频率和时间。
需要根据具体的应用程序和环境来确定采取哪些方法,可以结合监控和分析工具来进行调优和优化。
1.7之前扩容,map里的全部元素都需要refesh hash。
1.8之后,每次扩容为之前两倍,元素要么在原位置,要么在+len位。
为什么为两倍?
不为两倍容易hash冲突。
resize过程中可以均匀的把冲突节点分散到新的bucket。
Collection.sychronizedMap()(sychronized锁)
ConcurrentHashMap(新的锁机制,拆分hashmao,cas)性能好但代码繁琐
ConcurrentHashMap底层原理
1.7segement+entry
ThreadLocal又叫本地线程变量,在多线程并发执行的过程中,我们可以将某个变量存入ThreadLocal中,那么这个变量就可以看作专属于是该线程的本地变量,并且不受其他线程的干扰,从而达到对变量的安全访问。
1.7之前,threadlocal属于独立的一个类,自行管理生命周期。当需要用到时,thread向threadlocal里绑定一个key,之后thread从threadlocal里取val。
1.8之后,ThreadLocal是Thread类中的内部类。默认情况下为null。调用threadlocal.set时创建threadlocalmap,ThreadLocalMap是ThreadLocal的内部静态类,而它的构成主要是用Entry来保存数据 ,而且还是继承的弱引用。在Entry内部使用ThreadLocal作为key,使用我们设置的value作为value。
theadllocal会存在一些oom问题。因为threadlocalkey是弱引用,会被gc回收,但threadlocalval是强引用,这就会产生key为null的val。同时,threadlocal和线程绑定,但是由于线程池的存在,一个线程不会马上被删除,这就导致threallcoal会无限增加,如果不主动关闭。因此调用完threadlocal后要主动remove。
应用场景
hostholder保存用户状态数据替代session。
线程池
sleep、wait、join、yield
线程安全活跃状态、竞态条件