JAVA内存结构

一、Java文件编译的过程

在这里插入图片描述

  1. 程序员编写.java文件
  2. javac编译成字节码文件.class(JVM只认识.class文件)
  3. 在由JVM解释成电脑认识的机器语言

二、JVM、JRE、JDK

JVM:Java虚拟机,运行Java字节码文件.calss的虚拟机。

Java针对不同的系统平台都开发了对应的虚拟机,实现跨平台,一次编写,多处运行。JVM使用GC垃圾回收器和自适应优化器。

JRE:Java运行环境是一个软件,JRE为Java运行提供了环境。内部有一个Java虚拟机,以及一些标准的类库(Class Library)。

JDK:Java软件开发工具包,用于各种环境下的Java程序开发。是整个Java开发的核心,包含了JRE(JVM+Java类库Java API)和Java工具(Javac)。

JDK目录下有四个文件夹:bin、include、lib、 jre。

bin:最主要的是编译器(javac.exe)

include:java和JVM交互用的头文件

lib:类库

jre:java运行环境

总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。

三、JVM内存结构

在这里插入图片描述

JVM根据存储数据划分:

Heap:作用是存放对象实例和数组。所有线程共享的内存区域,存储程序运行时被创建的所有对象。在虚拟机启动时创建。分为新生代和老年代。GC管理的主要区域。

方法区 Method Area :存储被加载的类信息(元数据)、常量、静态变量、即时编译器编译后的代码等数据。所有线程共享的内存区域。方法区中有运行常量池,用于存放编译期的各种字面值和符号引用。别名叫作“非堆”。

Stack :线程私有,存储局部变量和中间结果。Java方法执行的线程内存模型。每个线程有自己的Java栈区,所有的这些变量都是创建在他们的线程的本地变量,在线程创建时栈区被创建,所有这些本地变量被称为线程本地变量。栈的单位是栈帧,一个方法一个栈帧。

程序计数器 PC register:存储当前正在执行的字节码指令的位置(行号)。在Java中,每个线程有自己独立的程序计数器。

由于JVM的多线程是通过线程轮流切换并分配处理器执行时间来实现,一个处理器只能执行一条线程中的指令。为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。也叫线程私有的内存。

本地方法栈为虚拟机使用到的本地(Native)方法服务。Native 方法是 Java 通过 JNI 直接调用本地 C/C++ 库,如notify,hashcode,wait等都是native方法。

四、JVM垃圾回收机制

四种引用:

在这里插入图片描述 

强引用:Object obj=new Object(),只要强引用关联还在,垃圾回收器永不回收被引用的对象。

软引用:系统将要发生内存溢出之前,软引用关联的对象会被回收。回收后还是空间不足,才会抛出内存溢出。

例如:一个程序用来处理用户上传的图片。若将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些使用较少的图片浪费内存空间,需要手动从内存中移除。如果每次打开图片都从磁盘文件中读取到内存再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都要访问磁盘,代价巨大。这个时候就可以用软引用构建缓存。

弱引用:一些有用但并非必须,弱引用关联的对象,只能生存大下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收。

虚引用:幽灵引用,最弱,随时会被回收掉。垃圾回收时收到一个通知,为了监控垃圾回收器是否正常工作。

对象存活判断:

引用计算和根可达分析俩种算法。

引用计算:判断对象的引用数量来决定对象是否可以被回收、每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。C++和Python采用这种算法,JVM并没有使用。

根可达分析:扫描堆中的对象,沿着GC Root对象为起点的引用链找该对象,找不到则证明此对象不可用。

垃圾回收算法:

当发生GC时,经过GC Roots算法判断为不可达的对象,就会进行对象回收。JVM对象回收主要有复制算法、标记清除、标记整理算法。

复制算法:将可用内存按容量划分为大小相等的两块,每次只使用其中一块。垃圾回收时,将所有存活的对象复制到另一块区域。然后对该区域进行整体清除。

标记-清除算法:标记所有需要回收的对象,标记完成后统一回收。

特点:会存在内存碎片,导致在程序运行中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发GC,执行效率不稳定,需要清理对象越多,效率越低。

标记-整理算法:

标记所有需要回收的对象,标记完成后,将存活对象整理到连续区域。然后将非存活对象清除。

特点:回收后堆空间规整,没有碎片。效率低,涉及到对象移动、引用更新、需要暂停用户线程。

五、Java内存管理

Java内存管理包括内存分配和内存回收两个方面。由JVM自动完成。

new一个Java对象时,即可视为为Java对象申请一个内存空间,JVM会在堆内存中为每个对象分配空间,当一个Java对象失去引用时,JVM的垃圾回收机制就会自动清除他们,并回收它们所占用的内存空间。

当Java对象被创建出来之后,垃圾回收机制GC会实时的监控每一个对象的运行状态。当监控到某个对象不在被引用变量所引用时,垃圾回收机制会立即回收它所占用的空间。

JVM的垃圾回收机制采用有向图方式来管理内存中的对象,可以方便的解决循环引用的问题。

当一个对象在堆内存中运行时,根据它有向图中的状态,可以把状态分为三种:

可达状态:当一个对象被创建后,有一个以上的变量引用它时。有向图中从起始顶点可以到该对象,那它就处于可达状态。程序可通过引用变量来调用该对象的属性和方法。

可恢复状态:若程序中某个对象不再有任何变量引用,它先进入可恢复状态。此时,系统的垃圾回收机制准备回收该对象所占用的内存。在回收之前,系统会调用该对象的finalize方法进行资源清理,如果在调用finalize方法重新让一个以上引用变量引用该对象,则这个对象会再次变为可达状态。否则,该对象将进入不可达状态。

当对象变成不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值