内存分析 垃圾回收

内存分析

虚拟机内存模型 (了解)

在这里插入图片描述

  • 程序计数器:在JVM规范中每个线程都有自己的程序计数器,存储当前线程正在执行的java方法的JVM地址, 即字段的行号。执行Native方法时,计数器为空。
  • Java虚拟机栈:每个线程创建时会创建一个虚拟机栈,生命周期与线程一致, 线程退出时,线程的虚拟机也会回收。虚拟机内部保持一个个的栈帧,每次调用方法都会进行压栈, JVM对栈帧的操作只有出栈和压栈两种,方法结束会进行出栈操作。
  • :几乎所有创建的java对象实例,都是直接分配到堆上的。会分为新生代,老年代划分,Java虚拟机在启动时,可以使用Xmx之类的参数指定堆区域的大小。
  • 方法区:方法区与堆一样,也是所有的线程所共享,存储被虚拟机加载的元(Meta)数据,包括类信息、常量、静态变量、即时编译器编译后的代码等数据。

程序执行过程内存分析 (重点)

  • Java 虚拟机的内存可以简单的分为三个区域:虚拟机栈 stack堆 heap
    方法区 method area

  • 虚拟机栈

    1. 每个方法被调用会创建一个栈帧
    2. JVM为每个线程创建一个栈
    3. 栈属于线程私有
    4. “先进后出,后进先出”
    5. 由系统自动分配,速度快,连续空间
    1. 存储创建好的对象和数组
    2. JVM只有一个堆,被所有线程共享
    3. 不是连续内存空间,分配灵活,速度慢
  • 方法区(静态区)

    1. 只有一个方法区,被所有线程共享
    2. 也是堆,用于存储类和常量相关的信息(不变的内容)
    3. 用来存储程序中永远不变或唯一不变的内容
  • 程序运行内存过程

public class Person {
	String name;
	int age;
	public void show(){
	System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class TestPerson {
	public static void main(String[ ] args) {
	// 创建p1对象
	Person p1 = new Person();
	p1.age = 24;
	p1.name = "张三";
	p1.show();
	// 创建p2对象
	Person p2 = new Person();
	p2.age = 35;
	p2.name = "李四";
	p2.show();
	}
}

在这里插入图片描述

参数传值机制

参数传值机制,包含了基本类型参数的传值和引用类型的传值

垃圾回收(了解)

内存管理

  • Java 的内存管理很大程度指的就是:堆中对象的管理,其中包括对象空间的分配和释放。
  • 对象空间的分配:使用 new 关键字创建对象即可
  • 对象空间的释放:将对象赋值 null 即可。垃圾回收器将负责回收所有”不可达”对象的内存空间。

垃圾回收过程

任何一种垃圾回收算法一般要做两件基本事情

  1. 发现无用的对象
  2. 回收无用对象占用的内存空间。

垃圾回收机制保证可以将“无用的对象”进行回收。无用的对象指的就是没有任何变量引用该对象。Java 的垃圾回收器通过相关算法发现无用对象,并进行清除和整理。

垃圾回收算法

引用计数法

一个店里面有四张桌子,每个桌子有一个计数员,当计数员看到桌子上没人的时候就可以回收桌子了。
在这里插入图片描述

循环引用

在这里插入图片描述

引用可达法
  • 程序把所有的引用关系看作一张图,从一个节点 GC ROOT 开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点

通用的分代垃圾回收机制

  • 分代垃圾回收机制,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。我们将对象分为三种状态:年轻代、年老代、持久代。同时,将处于不同状态的对象放到堆中不同的区域。 JVM将堆内存划分为 Eden、Survivor 和 Tenured/Old 空间。
年轻代
  • Eden区:所有新生成的对象首先放在Eden区,有个Minor GC会在Eden区满了之后立马启动清理内存
  • S1区:Minor GC清理后继续使用的对象会留在Sl区,其他不使用的就被清理了,在S1区满了之后Minor GC会统一清理S1区。
  • S2区:Minor GC清理S1区之后还在使用的对象留在S2区,其他没用的被清走,满了之后会放在年老代
年老代
  • 当年老代和年轻代都满了之后,Major GC和Full GC(全量回收),拉一次大扫除,全面清理年老代和年轻代。
永久代
  • 用于存放静态文件,如 Java 类、方法等。持久代对垃圾回收没有显著影响。

在这里插入图片描述

JVM调优和Full GC

在对JVM调优的过程中,很大一部分工作就是对Full GC的调节,有如下原因:

  • 年老代被写满
  • 永久代被写满
  • System.gc()被显示调用
  • 上一次GC之后help的各域分别配策略动态变化

开发中容易造成内存泄露的操作

  • 创建大量无用对象
  • 静态集合类的使用
  • 各种连接对象(IO 流对象、数据库连接对象、网络连接对象)未关闭
  • 监听器的使用不当

其他要点

  • 程序员无权调用垃圾回收器
  • 程序员可以调用 System.gc(),该方法只是通知 JVM,并不是运行垃圾回收器。尽量少用,会申请启动 Full GC,成本高,影响系统性能
  • finalize 方法,是 Java 提供给程序员用来释放对象或资源的方法,但是尽量少用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值