JVM从初始化到GC整个周期中发生的那些事(一)

xiaoxiao2021-02-28  9

生命周期的活动: 1.类加载器将类信息加载到方法区(也叫永久区,对应内内存中的Perm区),同时里面也存储的惊天 的成员变量。类信息包括方法,变量名,以及访问权限等等。 2.然后运行main函数,执行调用的类,根据方法区的内存作为模板,将类初始化到堆中存储,并且将调用的句柄放到栈中。 3这个时候执行类中的方法,调用方法必然有一个线程,jvm在创建线程的时候会在java栈中创建一块私有内存空间。用于存放局部变量,方法参数等该线程与方法的信息。这样保证每个线程执行的变量都是安全的。 线程中的参数虽然存储到私有栈中,这个值是从堆内存中复制过来的,这个时候就会线程安全的问题。私有栈中的肯定是安全的,这个概念不要模糊。不安全的是堆中的内存,因为线程执行后就会将拷贝的值赋值给堆中的原始值,这样多线程竞争的情况下,大家取值和写值都不是顺序的,必然混乱。这个时候就要说到Java的 volatile属性与java的线程安全机制。加上这个属性后,当两个线程同时读取一块堆中的对象或者值时,都将这个值复制到自己的私有栈中,当A线程改了这个值,B线程还没有改这个值,那么A线程就会将这个修改信号发送到堆中,然后jvm会根据堆内存中对该对象调用信息(记得是存在对象头中)将所有调用线程对这个属性的引用做处理(记得是失处理),这样在其他线程调用这个公用属性的时候,就会知道要重新读取这个公用变量。来达到线程安全的效果,如果想深入了解,请参考java的happen-before模型。(PS: 调用线程中,在执行方法的时候,应该有个嗅探的机制,有可能就是这个失效的处理,待研究和之后会单独补充) 4 对象调用完成后,如果不在使用,进入GC环节(PS:GC是jvm自己控制的,和对象使用结束的时间关系不大。赶上了就被回收,赶不上就赶着下次被回收),垃圾回收的算法有很多,比如引用计数法、标记压缩法、复制算法、分代分区等等。 引用计数发的机制是将对象应用一次就+1,取消引用就-1 这样当计数的值是0的时候就进行回收,这还是比较老的GC算法。如果对象被重复引用,这个算法就会有很大问题。 标记法的机制将对象引用的时候做个标记,不被引用时做另外的标记。这样回收的时候将标记为未被引用的对象进行回收,这个算法的弊端是由于对象在内存中时不连续的。所以有内存碎片的问题。 复制算法的机制是分配两块同样大小的内存,使用时候只使用其中一块,当进行回收的时候。将被使用的对象放到另一块内存中。然后清空本块内存。然后再反转这个操作。目前堆内存中的新生代就用的是这个算法。 标记压缩法是标记法的升级算法,就是在标记发的基础上对被标记不被GC的对象进行压缩到内存的一端,然后进行回收。解决了内存碎片的问题。 具体垃圾回收机制 、算法、jVM的优化策略详见下一章。
转载请注明原文地址: https://www.6miu.com/read-1100048.html

最新回复(0)