JVM入门,JVM基础

编写 .JAVA 文件 通过JAVAC 转换成 class文件 在通过虚拟机转换成电脑识别的文件

JVM整体划分

 运行时数据区:堆 和 方法区 线程共有,其他线程私有。

类加载 

加载,查找并加载类的二进制数据,在Java堆中也创建一个java.lang.Class类的对象。
连接,连接又包含三块内容:验证、准备、初始化。
1)验证,文件格式、元数据、字节码、符号引用验证;
2)准备,为类的静态变量分配内存,并将其初始化为默认值;
3)解析,把类中的符号引用转换为直接引用
初始化,为类的静态变量赋予正确的初始值。
 

加载,双亲委派模型

 当一个类收到类加载的请求,他不会首先加载这个类,而是将请求委派给父加载器去完成

自底向上寻找 在自顶向下 查找加载

自定义类加载:

继承ClassLoader  重写 findClass()方法

如何打破双亲委派模型:

重写 loadClass() 方法 

JIT即使编辑器

就是把这些Java字节码重新编译优化,生成机器码,让CPU直接执行。这样编出来的代码效率会更高。

编译也是要花费时间的,我们一般对热点代码做编译,非热点代码直接解析就好了。

热点代码解释:一、多次调用的方法。二、多次执行的循环体

运行时数据区

PC程序计数器

存放指令   程序计数器指的是当前线程正在执行的字节码指令地址(行号)  

ava中最小的执行单位是线程,因为虚拟机的是多线程的,每个线程是抢夺cpu时间片,程序计数器就是存储这些指令去做什么,比如循环,跳转,异常处理等等需要依赖它

每个线程都有属于自己的程序计数器,而且互不影响,独立存储。

虚拟机栈

一个方法 一个栈帧 

里边包含  局部变量表,操作数栈,动态链接,返回地址

大致应该是这样的~~~   main 是一个栈帧 c1 是一个栈帧

局部变量表:是变量值的存储空间,由方法参数和方法内部定义的局部变量组成,

操作数栈:后入先出栈,由字节码指令往栈中存数据和取数据,栈中的任何一个元素都是可以任意的Java数据类型。

动态链接:每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有该引用是为了支持方法调用过程中的动态连接。

返回地址:存放调用调用该方法的pc计数器的值。

本地方法栈

本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的

Java中的堆是用来存储对象本身的以及数组(数组引用是存放在Java栈中的)。堆是被所有线程共享的,在JVM中只有一个堆。

方法区

方法区 1.8前 Perm Soace  1.8后 Meta Space

与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。

在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,

对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。


GC垃圾回收

什么是垃圾?

在 C语言申请内存  C++ new delete        C/C++ 手动回收内存

java 自动回收内存

没有任何引用指向的一个对象或者多个对象(循环引用)

如何定位垃圾:

引用计数:看还有几个引用指向它

可达性分析 :简单来说 能到就不是垃圾 到不了就是   主要使用的是这种

常见垃圾回收算法:

标记清除 mark sweep :位置不连续 产生碎片 效率偏低(两遍扫描)

拷贝算法 copying:找出那些有用的,拷贝到另外一块内存去。 没有碎片,浪费空间

标记压缩  mark compact:有用的整理出来 扫描俩次,移动对象,效率偏低。 不会产生碎片,方便对象分配 不会产生内存减半。

分代垃圾回收算法:根据回收对象的特点进行选择,在jvm中,年轻代适合使用复制算法,老年代适合使用 标记清除或标记压缩算法。

JVM 内存分代模型

 1:2    可以通过参数来改变。  survivor 幸存区    1.8前 永久代 1.8后元空间

MinorGC/YGC:年轻代空间耗尽时触发

MajorGC/FullGC:在老年代无法继续分配空间时触发,新生代老年代同时进行回收

一个对象的出生到消亡:

->eden区->survivor( S0)(经过一次垃圾回收)->survivor2 (S1)->年龄够了 老年代

对象何时进入老年代

超过指定次数(YGC) 不设置就是默认参数 15

常见垃圾回收器

他们吧大部分是可以相互组合使用的

 Serial 单线程 Parallel 多线程 常见组合:(Serial+Serial Old)(Parallel Scavebge + Parallel Old) (ParNew + CMS)

Serial GC(串行收集器)应用特点:

1.内部只使用一个线程去回收(不能充分利用CPU的多核特性),无法并行化

2.GC过程可能会产生较长的时间停顿

Parallel Scavebge 年轻代 并行回收 与Serial 同理 但清理线程是多线程

ParNew 年轻代 配合CMS的并行回收

Concurrent Mark and Sweep (CMS) :老年代 并发的, 垃圾回收和应用程序同时运行,降低STW的时间

G1 : 三色标记 + SATB

三色标记: 白灰黑   SATB :关注引用的删除

JVM参数配置

运行时  配置  Run-> Edit Config........

-Xmn -Xms -Xmx -Xss
  年轻代 最小堆 最大堆 栈空间
-XX:+UseTLAB     使用TLAB,默认打开
-XX:+PrintTLAB  打印TLAB的使用情况
-XX:TLABSize  设置TLAB大小
-XX:+DisableExplictGC  
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-XX:+PrintGCTimeStamps
-XX:+PrintGCApplicationConcurrentTime   打印应用程序时间
-XX:+PrintGCApplicationStoppedTime   打印暂停时长
-XX:+PrintReferenceGC 
  记录回收了多少种不同引用类型的引用
-verbose:class  类加载详细过程
-XX:+PrintVMOptions         打印JVM运行时参数
-XX:+PrintFlagsFinal      -XX:+PrintFlagsInitial     
-Xloggc:opt/log/gc.log             gc日志
-XX:MaxTenuringThreshold
  升代年龄,最大值15

这个参数 太多了~~~~

在运行中 可以使用  工具来排查    可视化工具  jvisualVm   在  jdk /bin 目录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值