JVM-虚拟机垃圾回收机制探寻与代码优化

本文详细介绍了Java虚拟机(JVM)的概念及其在不同操作系统上的应用,重点讲解了JVM的垃圾回收(GC)机制,包括GC的发现与回收过程、常用的垃圾回收算法如标记清除、分段复制、标记整理以及分代收集算法,并提供了优化GC和避免内存泄漏的实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是JVM

JVM就是java虚拟机,JVM是java程序的运行平台,它就像一台虚拟出来的计算机一样,之所以称之为虚拟计算机是因为JVM中有自己想象的硬件,方法区、堆、本地方法栈、PC寄存器等,JVM负责执行Java编译好的字节码文件。JVM具有非常严格的实现规范,大多数操作系统都可以安装JVM,为Java语言的跨平台性起到了关键的作用。

二、JVM GC

GC是一种垃圾回收机制,为什么说GC是垃圾回收机制呢?就那C#来对比吧,在C#中当你创建一个对象但是这个对象用到了一半没有用了这个时候必须要手动回收对象,不然的话这样的对象越来越多的话,就会形成内存泄漏,而在java中有GC回收机制,简单的来说就是GC可以自动回收没有用的对象,但是GC不会总是存在GC会隔一会时间来一次,GC会根据自己给内存来调整清理的大小

  在学习Java GC 之前,需要记住一个单词:stop-the-world 。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行。当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成。GC优化很多时候就是减少stop-the-world 的发生。

三、发现与回收

发现垃圾

1.原始方法:引用计数法
	--一个对象被赋值给一个变量时,引用计数+1;
	--持有引用的变量退出作用域时,引用计数-1.
	
2.根搜索算法(GC Root)
	--栈帧里的局部变量所引用的对象;
	--方法区的静态变量和常量所引用的对象;

回收垃圾

1.标记清除法
    黑色的是垃圾对象,绿色空白内存,灰色的非垃圾对象
    比较直接是垃圾对象就腾出来
    缺点:很多碎片,没有连在一起,哪天我们要保存几G的文件就悲剧了,看起来空闲空间挺大,放一个完整文件又放不进去.
    
2.分段复制算法
  用一半留一半,用起来效率比较高
  需要清理时,把需要存留的对象copy到下面那一半,然后把上面全清空

3.标记整理算法
  算法比较复杂,但比较灵活,效率也比较高 尽量不往两头放,分配对象尽量往上面放,紧挨着
  每次回收就先整理一下,空白的一边,用过的一边,把不怎么用的放前面 不想分段算法那样严格,因为有时候可能已经用了一半多了.

4.分代收集算法
	伊甸园:西方故事里人刚出生的地方(刚new出来的对象就放着里面)
	生存区:又分From、To(分段法制法)
	From  :例如对象经历了5次回收还没被回收掉就证明它的生命周期应该比较长就把它放到From里来
	老年代:回收15次后还存在就有很大几率会一直使用移到老年代里来

知识点:
1.内存模型中几个重要区域的作用?

  方法区: 类class信息、静态属性、常量等堆:对象(数组也是对象)
  栈: 线程执行代码的地方,每个方法调用一一个栈帧( 局部变量、this引用)

JVM调整参数

调整堆内存大小:-Xms256M –Xmx512M
调整栈内存大小:-Xss2048k
调整方法区大小:-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=128M
调整方法区大小:-XX:PermSize=64M –XX:MaxPermSize=128M Java 7及以前适用

2.GC怎么发现垃圾?

2.1.引用计数法(无法发现相互引用的垃圾对象)
2.2.根搜索算法

3.GC怎么回收(清理)垃圾?

3.1.标记清除(简单),缺点是内存碎片,使用效率不高
3.2.分段复制法,用一半,留一半,缺点:动静太大
3.3.标记-整理算法
3.4.分代收集
伊甸园(最新对象)、生存区(From、 To区)、老年代、永久代(方法区)

4.高效代码的技巧、避免内存泄漏

尽量不要在循环中使用try…catch、new 对象;
把频繁使用的短命对象缓存起来;
尽可能使用栈内变量(方法内局部变量);
不要用异常来控制代码流程;
用线程池、连接池,不要自己创建;
学会读Java核心API源代码

5.干掉JVM

堆内存溢出: -Xms -Xmx调整 堆内存大小
OutofMemoryError: Heap space堆 内存溢出错误
方法区溢出: -XX:MetaspaceSize -XX :MaxMetaSpaceSize	调整方法区大小
OutofMemoryError: Metaspace方法区内存溢出
栈内存溢出: -Xss调 整栈内存大小
StackoverflowError:栈内存溢出
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值