【每日鲜蘑】学习JAVA必须知道的知识
简单收拾Java知识时,收拾的笔记,分享一下,如有错误,还请纠正,谢谢
编译进程
编译由 Java 源码编译器(javac)来完结。
进程:源代码—【词法剖析器】—Token 流—【语法剖析器】—语法树[ 5 K ? l ; e J—【语义剖析器】—注解抽象语法树—【字节码生成器】—JVM 字节码
三个进程
-
解~ o C q G G .析与填充符号表 -
注解处理 -
剖 5 } : 4 l析和字节码生成
语法糖【泛型】
泛型只会在 Java 源码中存在,编译往后会被替换为原来的原生类型(Raw Tyg v 1 K F E A i ;pe,也称为裸类型)了。这个进程也被称之为“泛型擦除”。
-
代码愈加简练【不用强制转化】 -
程序愈加强健【只要编译时期没有警告,那么运转时期就不会呈现 ClassCas7 { s & N x –tException 反常】 -
可读性和安稳性【在编写调集的时分,就限定了类型】
跨! ? v M I ( p L渠道运转
字节码是不区别w f | | ( Y D –体系的,而 JDK 是区别体系的= c r 5 r : q _ W。各个渠. M A道编译的字节码都契合 JVM 的标准,然后做到一次编译到处运转。
类的加载
不是一切的类都会被加载到 JVM 的,Java 类的加载是动态的,只要在需要用到的时分才会被加载,这样节省了内存开销。
默许的类加载器
-
发动类加载器:【Bootstra_ 5 )p ClassLoader】担任加载$JAVA_HOME 中 jrX b h ! ^ S % Se/lib/rt.jar里一切的 class,由 Cr 9 a * D C | h++完结,不是 ClassLoader 子类。 -
扩展类加载器【Extension ClassLoader】担任加载 javx ~ ?a 渠道中扩展功用的一些 jar 包,包括$! B _JAVA& x a d g u_HOME 中 jre/lib/*.jar 或-Djava.ext.dirs 指定目录下的 jar 包。 -
应用类加载器【Application ClassLoader】担任记载clT c V 1 F O N Basspath中指定的 jar 包及目录中 class。 -
用户自定义类加载器【User ClassLoadder】
双亲派遣【处理安全性问题】
假如一个类加载器收到了类加载的恳求,它首要不会6 C ? w A 6 # D自己去测验加载这个# 7 s = w = ! y N类,而是把恳求托付给父加载器去完结,依次向上。
-
优点: 避免内存中呈现多份相同的字节码(安全性角度)
类加载器在成功加载某个类之后,会把得到的 java.lang.Class 类的实例缓存起来。下次再恳求加载该类的时分,类加载器} i 4 | 2 3 } 6会直接运用缓存的类的实例,而I 4 . Q # t ]不会测验再次加载。
经过自定义 ClassLoader,并重写父类的 loadClass 办法能够打破双亲派遣的机制,6 d m : 4 k而 Java 的 SPI(服务供给发现机制)也是打破双亲派遣机制的。
详细进程
-
加载,查找并加载@ . ; # q e 2类的二进制数据,在 Java 堆中也创立一个 java.% : + R _ mlang.Class 类的方针。 -
衔接,衔接又K & , V . s K包括三块内容:验证、预备、初始化。 -
1)验证,文件格局、元数据、字节码、符号引用验证; -
2)预s s a备,为类的静态变量分配内存,并将其初始化为默许值; -
3)解析,把类中的符号引7 w ~ | ~ B % O X用转化为直接引用
-
-
初始化,为类的静态变量赋予正确的初始值。
JIT 即时编译器
【Just In Time】将热门代码的P l G 4 A字节码从头编译优化z J b 9 { = * { t,让 CPU 直接履行,这样的履行效率会更高。HotSpot 是依据计数器来检测热门代码的而非采样。
类加载完后
在类加载查看通往后,接下来虚拟机将为新生方针分配内存。
JVM 的废物收回算法
经过“可达性剖析f , i j算法”剖析哪些方针是废物,然后经6 c M {过废物收回算法进行收回。
-
Serial 收集器,串行收集器是最陈旧,最安U K ! p稳以及效率高的收集器,但可能会产生较长的中止,只运用一个线程去收回。 -
ParNew 收集器,ParNew 收集器其实便是 Serial 收集器的多线程版别。 -
Parallel 收集器,Parallel Scave* l ` 5 wnge^ ~ R g 收集^ U T {器类似 ParNew 收集器,Parallel 收集器更重视体系的吞吐量。 -
Parallel Old 收集器,Parallel Old 是 Parallel ScS ] D =avenge 收集器的老时代版别,运用多线程“标记-收U I 0 _ @ P w ~拾”算法 -
CMS 收集器,CMS(Concurrent Mark Sweep)收集器是一种以获取最短收Z r O回中止时刻为方针的收集器。它需要消耗额外的 CPU 和内存资源,在 CPU 和内存资源紧张,CPU 较少时,会加重体系担负。CMS无法处理浮动废物。CMS 的“标记-铲除”算法,会导致大量空间碎片的产生。 -
G1 收集器,G1 (Ga1 ! , U o 7 /rbage-First)是一款面向服务器的废物收集器,首要针对装备多颗处理器及大容量内存的机器. 以极高概率满足 Gg 6 ( [C 中止时刻要求的同时,还具有高吞吐量性能N V 1 ] 5 –特征。
JVM 内存模型
JVM 内存共分为虚拟机栈、堆、办法区、程序计数器、本地办法栈五个部分。
栈| ! D $ *管运转,堆3 – ) T V ? G g管存储。
JVM 内存会划分为堆内存和非堆内存,堆内存中也会划分为年青代和老时代,而非堆内存则为永久代(办法区、元空间)。
年? ! = 6 D r青代Y b h l 1 @ c Z E又会分为 Eden 和 Survivor 区。Survivor 也会分为 Fr3 } / { y _ $omPlace 和 ToPlace,toPlac] % c 7 %e 的s ` / t ] r c survivor 区域是空的。Eden,FromPlace 和 ToPlace 的默许占比为 8:1:1。
当然这个东西其实也能够经过一个 -XX:+UsePSAdaptiveSurvivorSizePolicy 参数来依据生成方针的 { r C +速率动态调整
内存走漏&amV % z . ; R yp;内存溢出
-
内存走e h g C #漏:方针可9 1 H b f * a x达,但是s ? g方针不会被运用。 -
内存溢出:装载类的空间不行、内存空间缺乏、内存走漏等等都可能导0 L E & q h a T t致溢出。
线程栈
JVM 标准让每个 Java 线程具有自己的独立的 JVM 栈,也便是 JQ | G z : Pava 办法的调用栈。
当办法调用的时分,会生成一个栈帧。栈帧是保存在虚拟机栈中的,栈帧存储了办法的局部变量表、操作数栈、动态衔接和办法返回地址等信息
线程运转进程中,只要一个栈帧是处于活泼状态,称为“当时活泼栈帧”,当时活动栈帧始j % p %终是虚拟机栈的栈顶元素。
JVM7 ` & = 年青代到年迈代的提升进程的判别条件是什么
-
部分方针会在 From 和 To 区域中仿制来仿制去,如此交流 15 次(由 JVM& L r 参数 MaxTenuringThreshold 决定,这个参数默许是 15),终究假如还是存活,就存入到老时代; -
假如方针的大小大于 Eden 的二分之一会直接分配在* j t old,假如 old 也分配不下,会做一次 majorGC,假如小于 eden 的一半但是没有满足的/ 4 ! A o空间,就进行 minorgc 也便是新生代 GC; -
minor gc 后,survivor 依然放不下,则放到老时代; -
动态年龄判别 ,大于等于某个年龄的方针超过了 survivor 空间一半 ,大于等于某个年龄的方针直接进入老时代;
JVM 呈现 fullGC 很频频,怎么去线上排查问题
-
是不是频频创立了大方针(也有可能 eden 区设置过小)(大方针直接分配在老时代中,导致老时代空间E S q缺乏—>然后频频 gc) -
是不Q U r O T c是老时代的空间设置过小了(Minor GC 几个方针就大于老时代的剩下U q Y H L ` ,空间了) 1. 假如一次 full GC 后,剩下方针不多,那么阐明 Eden 的空间设置太小[ R E 3 & r,导致大量短生命周期的方针被分配到了老生代。 2. 假如一次 full GC 后,老生代的变化不大,那么是老生代分配空间太小了。
JVM 废物收回机制,何时触发 MinorGC 等操作 ; ~ O C [
-
当 young gen 中的 eden 区别配满的时分触7 0 p发 MinorGC(新生代的空间不行放的时分).