21-Spring_JVM-1

本文介绍了Java的内存空间,包括方法区、堆内存区、栈区和本地方法栈。阐述了垃圾回收机制原理,以对象可达性判断是否回收。还讲解了堆内存划分,包括新生代和老年代,以及复制算法。此外,介绍了多种垃圾回收算法和三种GC类型。

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

1.内存空间

方法区:类的信息,常量,静态,这一块的区域,一般是不进行回收的,但是如果满了以后,有一个叫做Full GC的也会回收方法区的东西

堆内存区heap:一些new出来的obj,堆内存区,是辣鸡回收机制主要回收内存的地方

栈区stack:主要存放基本数据类型,局部变量

本地方法栈:这里是java要使用别的语言库的一个内存区,所有的func要加native修饰

2.垃圾回收机制原理

以对象是否可达,最为判断点

如果一个obj没有被别的对象引用,那么这个对象就是不可达,反之就是可达的对象

finalize()方法是回收机制在回收前会调用的一个方法,这里肯定是要new一个obj的子类,直接new一个obj肯定不行,因为finalize()方法是一个需要子类重写的方法.

System.gc() 会提示垃圾回收机制进行垃圾回收,但是不是立即执行的

3.堆内存划分:

这是一个很核心的知识点

堆内存划分为: 新生代 + 老年代

其中 新生代 = eden + s0(又叫from区) + s1(又叫to区)

eden区:主要的内存回收发生在这里

s0区:

s1区:

这2个区必须要一起来讲:s0区和s1区的内存大小一样,当我们eden区的obj,在进行了若干次的被引用后,会跑到s0区,在一段时间过后,如果s0区的对象,有一些不可达了,那么s0区可达的对象,会被全部复制到s1区,然后gc会把s0区所有不可达的obj删除,然后同样,再过一段时间以后,s1区如果有一些不可达的对象需要被回收,那么s0会从s1区复制s1区所有的可达的对象,然后再把s1区所有的不可达对象删除 --> 以上就被称之为复制算法

复制算法有一个很大的优点就是:避免了碎片化

默认   新生代:老年代 = 1 :2

新的obj在引用计数到了15次以后,就会从新生代跑到老年代去,这里的引用计数法,跟oc里面的引用计数,几乎是一模一样,这里用"几乎"是怕有不同的地方,在我看来原理就是完全一样的

3.垃圾回收机制的算法

引用计数法:这里几乎就是跟oc中的引用计数法一样,在这里被jvm淘汰,是因为循环引用...但是在oc里面使weakself来避免循环引用

根搜索法:GCRoots

如果一个对象,跟GCRoots对象连在一起,那就说明,这个对象是可达的,那么就不会被回收

方法区,本地方法栈,虚拟机栈,这些都可以作为一个GCRoots对象

标记清除算法:

用状态码标定一个对象是否存活,然后垃圾回收机制会根据这个状态码,来进行回收

但是,这里会产生一个碎片化的问题,这种单个回收,肯定会带来碎片回收的问题,回收也会有残余,这个涉及到硬盘硬件原理...

所以,这里不适合做新生代的垃圾回收处理,一般都用于老年大的垃圾回收.

标记压缩算法:

把可达对象和不可达对象,分别划为2个阵营,这样,在清除不可达对象的时候,就可以一把清除了

分代算法:

对内存中的垃圾按照实际情况综合清理

4.三中GC

minorGC:主要用于回收新生代的垃圾

majorGC:主要用于回收老年代的垃圾

fullGC:新生代和老年代都会回收

<think>我们正在编写一个BAT脚本来启动JAR包,并传递指定的系统参数(以-D开头的参数)。这些参数是JVM参数,通常在java命令后面直接传递。步骤:1.确定java可执行文件的路径。如果系统中已经配置了JAVA_HOME环境变量,我们可以使用它;否则,我们可以直接使用"java",但这样需要确保java在PATH中。2.编写启动命令:java[系统参数]-jarjar包路径3.将用户提供的系统参数(-D开头的参数)放在-jar之前。注意:BAT脚本中,如果路径包含空格,需要使用双引号括起来。根据用户需求,需要传递的参数有:-DNACOS_NAMESPACE=8cba1e0a-f8e2-4979-a182-9bdbc05e1af2-DNACOS_SERVER_ADDR=10.251.22.122-DNACOS_SERVER_GROUP=GROUP_DEV-DAPPLICATION_NAME=smics-gateway我们假设JAR包的路径是当前目录下的某个jar文件,例如gateway.jar(实际脚本中可能需要根据实际情况修改)。脚本示例:```bat@echooffrem设置JAVA_HOME,如果已经配置了环境变量则不需要,但这里我们优先使用JAVA_HOMEsetJAVA_HOME="C:\ProgramFiles\Java\jdk1.8.0_291"rem如果已经配置了JAVA_HOME环境变量,则不需要上面这行,可以直接使用%JAVA_HOME%rem如果不想设置JAVA_HOME,也可以直接使用java命令(确保在PATH中)setJAVA_EXE=%JAVA_HOME%\bin\java.exeifexist%JAVA_EXE%(setJAVA_CMD=%JAVA_EXE%)else(setJAVA_CMD=java)rem设置要传递的JVM参数setJVM_OPTS=-DNACOS_NAMESPACE=8cba1e0a-f8e2-4979-a182-9bdbc05e1af2-DNACOS_SERVER_ADDR=10.251.22.122-DNACOS_SERVER_GROUP=GROUP_DEV-DAPPLICATION_NAME=smics-gatewayrem设置JAR包的路径,这里假设jar包在当前目录下,名为gateway.jarsetJAR_PATH=gateway.jarrem启动Java应用程序%JAVA_CMD%%JVM_OPTS%-jar%JAR_PATH%pause```但是,如果用户希望更灵活地指定JAR包名称,或者参数有空格等情况,我们需要注意引号的使用。另外,上面的脚本中,如果JAVA_HOME没有设置,我们回退到使用java命令(要求java在PATH中)。如果用户已经设置了全局的JAVA_HOME环境变量,那么我们可以直接使用%JAVA_HOME%而不需要在脚本中写死。所以,更好的做法是:方案1:不设置JAVA_HOME,直接使用java命令(要求PATH配置正确)。方案2:在脚本中检查是否配置了JAVA_HOME环境变量,如果没有,尝试使用java命令。改进版本:```bat@echooffrem尝试使用JAVA_HOME环境变量ifdefinedJAVA_HOME(set"JAVA_EXE=%JAVA_HOME%\bin\java.exe")else(rem如果JAVA_HOME未定义,则检查java命令是否在PATH中setJAVA_EXE=java)rem设置JVM参数setJVM_OPTS=-DNACOS_NAMESPACE=8cba1e0a-f8e2-4979-a182-9bdbc05e1af2-DNACOS_SERVER_ADDR=10.251.22.122-DNACOS_SERVER_GROUP=GROUP_DEV-DAPPLICATION_NAME=smics-gatewayrem设置JAR文件路径(这里使用当前目录下的gateway.jar,可以根据需要修改)setJAR_FILE=gateway.jarrem检查jar文件是否存在ifnotexist"%JAR_FILE%"(echoError:JARfile'%JAR_FILE%'notfound.pauseexit/b1)rem执行命令"%JAVA_EXE%"%JVM_OPTS%-jar"%JAR_FILE%"rem保持窗口,以便查看输出(如果不需要,可以去掉pause)pause```注意:上面的脚本中,如果JAVA_EXE被设置为java,那么命令执行时会直接使用java,因为它在PATH中。如果java.exe不在PATH中,则可能会报错。另外,如果参数值包含空格,那么必须用引号括起来。例如:-Dsome.arg="valuewithspace"。但用户提供的参数中似乎没有空格,所以可以不用。但是,为了通用性,我们可以考虑将每个参数都加上引号,但这样并不正确,因为JVM参数中的空格是特殊处理的。通常,每个-D参数都是一个整体,如果参数值有空格,则整个-D表达式(即从-D开始到下一个空格之前)会被当作一个参数。所以,当参数值有空格时,我们需要用双引号将整个值括起来,例如:-Dparam="argwithspace"由于用户提供的参数中没有空格,所以我们可以按照上面的方式书写。如果用户需要启动的jar包不在当前目录,那么可以设置绝对路径或相对路径,例如:setJAR_FILE=..\lib\gateway.jar最后,如果启动后希望关闭窗口(不暂停),可以移除最后的pause命令。因此,最终脚本可以如下(根据实际调整):</think> ### 如何在 Windows 编写 BAT 脚本启动 JAR 包并传递系统参数 以下是完整的 BAT 脚本解决方案,支持传递指定的系统参数(`-D` 参数)并启动 JAR 包: ```batch @echo off setlocal enabledelayedexpansion :: ======== 可修改的配置部分 ======== :: 1. 设置JVM参数(根据实际需求修改) set JVM_OPTS=-DNACOS_NAMESPACE=8cba1e0a-f8e2-4979-a182-9bdbc05e1af2 ^ -DNACOS_SERVER_ADDR=10.251.22.122 ^ -DNACOS_SERVER_GROUP=GROUP_DEV ^ -DAPPLICATION_NAME=smics-gateway :: 2. 设置JAR文件路径(替换为您的实际路径) set JAR_PATH=your_application.jar :: 3. 设置Java安装路径(可选,如果配置了环境变量可删除) :: set JAVA_HOME="C:\Program Files\Java\jdk-17.0.1" :: ======== 执行启动命令 ======== :: 检查Java环境 if defined JAVA_HOME ( set "JAVA_EXE=%JAVA_HOME%\bin\java.exe" ) else ( set "JAVA_EXE=java" ) :: 启动应用 echo 正在启动应用,参数:%JVM_OPTS% "%JAVA_EXE%" %JVM_OPTS% -jar "%JAR_PATH%" :: 保留窗口查看输出 pause ``` ### 使用说明: 1. **修改配置** - 替换 `JAR_PATH` 为您的实际 JAR 文件路径 - 根据需要调整 `JVM_OPTS` 中的参数值 - 如果系统未配置 JAVA_HOME,取消注释 `set JAVA_HOME=...` 并填写实际路径 2. **保存脚本** - 将代码保存为 `.bat` 文件(如 `start_app.bat`) 3. **运行方式** - 双击运行或在 CMD 中执行脚本 - 窗口将保持打开状态显示程序输出 ### 关键参数说明: | 参数 | 说明 | 示例值 | |------|------|--------| | `-DNACOS_NAMESPACE` | Nacos 命名空间ID | `8cba1e0a-f8e2-4979-a182-9bdbc05e1af2` | | `-DNACOS_SERVER_ADDR` | Nacos 服务器地址 | `10.251.22.122` | | `-DNACOS_SERVER_GROUP` | Nacos 分组名称 | `GROUP_DEV` | | `-DAPPLICATION_NAME` | Spring 应用名称 | `smics-gateway` | > **注意**:参数中的 `^` 是 BAT 脚本的换行符,确保所有参数在同一个 set 命令中定义[^1] --- ### 相关问题 1. 如何在启动脚本中添加 JVM 内存参数(如 -Xmx)? 2. BAT 脚本如何后台运行 Java 程序? 3. 当需要传递动态参数时,如何修改脚本从命令行接收输入? 4. Windows 服务方式运行 Java 应用的配置方法? [^1]: BAT 脚本中 `set` 命令的特殊字符处理规范(Microsoft Docs)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值