认识JVM和运行时内存

认识JVM和运行时内存

基本概念:JVM运行Java代码的假想计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收、一个堆、一个存储方法域。

JVM与硬件没有直接交互,运行在操作系统之上。

运行过程

  1. Java源文件---->编译器---->字节码文件

  2. 字节码文件---->JVM解释器---->机器码

内存区域

运行时数据区:方法区、堆、栈、本地方法栈、计数器

1、线程

JVM允许一个应用并发执行多个线程。JVM中的Java线程与操作系统线程有直接的映射管理。

  1. 当线程本地存储、缓冲区分配、栈等准备好之后,就会创建一个操作系统原生线程。

  2. 当原生线程初始化完毕,就会调用Java线程的run方法。

  3. Java线程结束时,会释放原生线程和Java线程的所有资源。

JVM后台线程:

  1. 虚拟机线程:

  2. 周期性任务线程:负责定时器事件

  3. GC线程:垃圾回收活动

  4. 编译器线程:将字节码动态的编译成本地相关的机器码

  5. 信号分发线程:接收发送到JVM的信号并调用JVM方法

2、内存区域

主要包括:

  1. 线程私有:计数器、栈、本地方法区

  2. 线程共享:堆、方法区

  3. 直接内存(不收JVM GC管理)

生命周期:

  1. 线程私有数据区域生命周期与线程相同,依赖用户线程的启动、结束、创建、销毁。

  2. 线程共享区域随JVM的启动/关闭而创建/销毁。

  3. 直接内存不属于运行时数据区的一部分。

2.1 程序计数器(线程私有)

当前线程所执行的字节码的行号指示器。

特点:唯一一个没有规定任何OOM的区域

2.2 虚拟机栈(线程私有)

java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成,就对应了一个栈帧在虚拟机栈中入栈和出栈的过程。

2.3 本地方法区(线程私有)

栈为执行Java方法服务,而本地方法栈则为执行Native方法服务。

2.4 堆(线程共享)

创建的对象和数组都保存在Java堆内存中,也是垃圾收集器进行垃圾收集的最重要的区域。GC采用分代收集算法,因此堆从GC的角度还可以分为:新生代(Eden、FS、TS)和老年代。

2.5 方法区/永久代(线程共享)

用于存储JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,

3、运行时内存

堆空间内部,新生代1/3,老年代2/3

新生代内部,Eden:from:to=8:1:1

新生代:

Eden区:Java新对象的出生区,新对象太大会直接分配到老年代。Eden区内存不够时,触发MinorGC。

MinorGC过程:复制-清空-互换

复制:Eden区和from区存活的对象赋值到to区,年龄+1,达到老年标准就复制到老年区;

清空:清空Eden和from;

互换:to和from互换,to成为下一次GC的from区;

老年代:

老年代内存不足时触发MajorGC,或者新对象太大也会提前触发一次MajorGC。

MajorGC采用标记清除算法:扫描,标记存货的对象,回收没有标记的对象。会产生内存碎片,进行合并。

老年代也装不下的时候,抛出OOM异常。

永久代:存放Class、元数据信息,Class在加载的时候被放入永久区域。

JAVA8,永久代被移除,由元空间取代。最大的区别是,元空间不在JVM中,而是使用本地内存,这样加载的类的元数据由系统的实际可用空间来控制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值