别人帮自己做网站有后门吗,wordpress腾讯云CDN配置,网站开发经验总结与教训,深圳教育集团网站建设目录
一、System.gc()的理解
二、内存溢出与内存泄露
#xff08;一#xff09;OOM
#xff08;二#xff09;内存泄露
三、StopTheWorld
四、垃圾回收的并行与并发
五、安全点与安全区域
#xff08;一#xff09;安全点
#xff08;二#xff09;安全区域
…目录
一、System.gc()的理解
二、内存溢出与内存泄露
一OOM
二内存泄露
三、StopTheWorld
四、垃圾回收的并行与并发
五、安全点与安全区域
一安全点
二安全区域
六、引用
一强引用
二软引用
三弱引用
四虚引用
五终结器引用 一、System.gc()的理解
System.gc或Runtime.getRuntime().gc()的调用会显示触发FullGC同时会对老年代和新生代进行回收尝试释放被丢对象占用的内存。然而System.gc调用无法保证对垃圾收集器的调用即运行这行代码并不一定会产生垃圾回收。
一些特殊情况下比如编写性能基准我们可以在运行之间调用System.gc
二、内存溢出与内存泄露
一OOM
1、java 虚拟机的堆内存设置不够
2、代码创建大量大对象并且长时间不能被垃圾收集器收集存在被引用
二内存泄露
只有对象不再被程序用到了但是GC又不能回收他们的情况才叫内存泄露
实际情况有一些疏忽导致对象的生命周期变的很长甚至OOM宽泛意义上的内存泄露
举例
单例的生命周期和程序是一样长如果单例程序中持有对外部对象的引用的话那么这个外部对象是不能被回收的导致内存泄露一些提供close的资源未关闭导致内存泄露如数据库链接网络链接和IO
三、StopTheWorld
指的是在垃圾回收线程工作时停止用户线程的一种情况也称为STW。
四、垃圾回收的并行与并发
首先理解最基本的并行与并发
并发同一时间段内几个程序都在同一个处理器上运行 CPU切换
并行一个CPU执行一个进程时另一个CPU可以执行另一个进程两个进程互相不抢占资源可以同时进行我们称之为并行 并行因素取决于CPU的核心数量 并发的多个任务之间抢占资源并行多个任务之间不互相抢占资源
垃圾回收器中的
串行指的是单个垃圾回收线程串行执行例如Serial收集器并行指的是多个垃圾回收线程并行执行例如ParNew收集器并发指的是垃圾回收线程和用户线程并发执行例如CMS收集器 五、安全点与安全区域
一安全点
程序执行并非在所有地方都能停顿下来开始GC只有特定的位置才能停顿下来开始GC这些位置称为安全点 有了安全点的设定也就决定了用户程序执行时 并非在代码指令流的任意位置都能够停顿下来开始垃圾收集而是强制要求必须执行到达安全点后才能够暂停。因此安全点的选定既不能太少以至于让收集器等待时间过长也不能太过频繁以至于过分增大运行时的内存负荷。安全点位置的选取基本上是以“ 是否具有让程序长时间执行的特征 ” 为标准进行选定的因为每条指令执行的时间都非常短暂程序不太可能因为指令流长度太长这样的原因而长时间执行“ 长时间执行 ” 的最明显特征就是指令序列的复用例如方法调用、循环跳转、异常跳转等都属于指令序列复用所以只有具有这些功能的指令才会产生安全点。 对于安全点另外一个需要考虑的问题是如何在垃圾收集发生时让所有线程这里其实不包括 执行 JNI 调用的线程都跑到最近的安全点然后停顿下来。这里有两种方案可供选择抢先式中断 Preemptive Suspension 和主动式中断 Voluntary Suspension 抢先式中断 中断所有线程如果还有线程不在安全点就恢复线程让线程跑到安全点没有虚拟机采用主动式中断 设置一个中断标志各个线程运行到安全点的时候主动轮询这个标志如果标志为真则将自己进行中断挂起
二安全区域
如果线程处于sleep或者blocked状态这时候线程无法响应jvm中断请求走到安全点去中断挂起。对于这种情况就需要安全区域来解决
安全区域是指在一段代码片段中对象的引用关系不会发生变化在这个区域中任何位置开始GC都是安全的。
当线程运行到安全区域代码时首先标志已经进入了安全区域如果GCJVM会忽略标识为安全区域状态的线程
当线程即将离开安全区域时会检查JVM是否已经完成GC如果完成了则继续运行。否则线程必须等待直到收到可以安全离开安全区域的信号为止
六、引用
Java中有五种引用 一强引用
强引用是最传统的引用定义程序代码中普遍存在的引用赋值类似new Object这种引用关系无论任何情况下强引用存在垃圾收集器永远不会回收掉被引用的对象
强引用是造成java内存泄露的主要原因之一强引用可以直接访问目标对象
二软引用
若某个对象被软引用当gc一次后内存仍然紧张时该对象在第二次gc会被回收
三弱引用
若某个对象被弱引用当gc发生时该对象会被回收 注软和弱引用不一定要配合引用队列引用队列每个引用自身也会占用一定的内存当其指向的对象被垃圾回收时也可以将引用入队然后通过referenceHandler来定期查看队列是否有新的引用入队然后进行清除引用回收内存 四虚引用
一个对象是否有虚引用存在完全不会对其生存时间构成影响。唯一目的就是在这个对象被收集器回收时收到一个系统通知。它不能单独使用也无法通过虚引用获取被引用的对象。
比如bytebuffer被回收时其分配的直接内存没有释放此时虚引用入队Cleaner通过底层调用Unsafe.freeMemory()方法来释放直接内存由Reference Handler线程调用虚引用相关方法释放直接内存
五终结器引用
Object有一个finallize方法。当我们重写该方法且该对象没有强引用指向它时虚拟机会生成一个终结器引用在第一次gc的时候将引用加入引用队列此时对象并没有被回收然后会有一个优先级较低的finallizeHandler线程查看队列是否有终结器引用如果有就调用其指向对象的finallize终结方法然后下一次gc的时候该对象和对应的终结器引用就可以被回收了 注虚和终结器引用一定要配合引用队列