JVM和GC详解

一、JVM内存模型

JVM和GC详解
JVM中的运行时数据区由方法区(永久代)、java堆、java栈、程序计算器、本地方法栈组成。
1.方法区:方法区是被所有线程共享区域,用于存放已被虚拟机加载的类信息,常量,静态变量等数据。被Java虚拟机描述为堆的一个逻辑部分。习惯是也叫它永久代(permanment generation)
    永久代也会垃圾回收,主要针对常量池回收,类型卸载(比如反射生成大量的临时使用的Class等信息)。
    常量池用于存放编译期生成的各种字节码和符号引用,常量池具有一定的动态性,里面可以存放编译期生成的常量;运行期间的常量也可以添加进入常量池中,比如string的intern()方法。
    当方法区满时,无法在分配空间,就会抛出内存溢出的异常(OutOfMemoneyError)。
java8中已经没有方法区了,取而代之的是元空间(Metaspace)。

2.java堆:堆是被所有线程共享的区域,实在虚拟机启动时创建的。堆里面存放的都是对象的实例(new 出来的对象都存在堆中)。我们平常所说的垃圾回收,主要回收的就是堆区。

3.java栈:java虚拟机栈是线程私有,生命周期与线程相同。创建线程的时候就会创建一个java虚拟机栈。java虚拟机栈里面存放的都是方法、基本类型,虚拟机执行java程序的时候,每个方法都会创建一个栈帧,栈帧存放在java虚拟机栈中,通过压栈出栈的方式进行方法调用。采用先进后出,也就是main方法最先执行,会存到栈的最底部,最后才结束。

4.程序计算器:程序计数器就是记录当前线程执行程序的位置,改变计数器的值来确定执行的下一条指令,比如循环、分支、方法跳转、异常处理,线程恢复都是依赖程序计数器来完成。
    Java虚拟机多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。为了线程切换能恢复到正确的位置,每条线程都需要一个独立的程序计数器,所以它是线程私有的。
    如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

5.本地方法栈:与虚拟机栈基本类似,区别在于虚拟机栈为虚拟机执行的java方法服务,而本地方法栈则是为Native方法服务。(栈的空间大小远远小于堆)

二、GC怎么发现垃圾

1.引用计数算法:在对象头中分配一个空间来保存该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加一,如果删除对该对象的引用,那么它的引用计数就减一,当该对象的引用计数为0时,那么该对象就会被回收。但是如果两个垃圾对象相互引用,那么这两个垃圾对象的引用计数永远不为0。所以这是GC回收最简单最low的一种算法。如图:
JVM和GC详解
2.根搜索算法:我们将方法区、栈作为根,如果堆中的对象被引用就会和根之间有一条引用链。GC从根开始作为起始点,从这些节点开始往下搜索,没有引用链可达时,则证明此对象是不可用的,这样的对象被判定为是可回收的。这样就可以解决堆中的垃圾对象相互引用也跑不掉被回收的命运。如图:
JVM和GC详解

三、GC怎么回收(清理)垃圾

1.标记清除算法:简单,但是会产生大量的内存碎片,未使用和使用过的空间交错杂乱,大内存数据存取时需要搜索足够让它存储的空间,效率不高。如图:
JVM和GC详解

2.分段复制算法:用一半,留一半,回收时将不需要回收对象的copy到下面那一层,只回收上面那层,缺点是要不断的去copy和移动对象,动静太大。如图:
JVM和GC详解

3.标记-整理算法:让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。如图:
JVM和GC详解

4.分代收集算法:当前商业虚拟机的垃圾收集都采用“分代收集”(Generational Collection)算法,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代、老年代和永久代(方法区),这样就可以根据各个年代的特点采用最适合的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用分段复制算法,只需要付出少量存活对象的复制成本就可以完成。而老年代中因为对象存活率高、没有额外空间对他进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收。如图:
JVM和GC详解

四、如何编写高效、健壮的java程序

JVM和GC详解

五、内存泄漏和内存溢出

内存泄漏是指程序里有无法被回收的对象。
内存溢出是指程序在申请内存时,没有足够的内存空间供其使用。大多数原因都是因为内存泄漏产生大量无法回收对象占用大量内存,导致内存溢出。

溢出报错
JVM和GC详解

分享福利

JVM和GC详解
JVM和GC详解
我一般用来充会员,视频VIP;会员、vip到期时间最快一个月,价格比官方的要便宜许多,买了不亏,走运可以用个一两年,我充的第一次qq超级VIP大概用了一年多,现在还在,不说了上网址:http://member.12mx.cn/