橘子学JDK之JMH-02(BenchmarkModes)

2024-04-09 12:28
文章标签 jdk 02 橘子 jmh benchmarkmodes

本文主要是介绍橘子学JDK之JMH-02(BenchmarkModes),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、案例二代码

这次我们来搞一下官网文档的第二个案例,我删除了一些没用的注释,然后对代码做了一下注释的翻译,可以看一下意思。

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.Throughput, as stated in its Javadoc, measures the raw throughput by* continuously calling the benchmark method in a time-bound iteration, and* counting how many times we executed the method.** We are using the special annotation to select the units to measure in,* although you can use the default.** AI直译:Mode.Throughput,如其Javadoc所述,通过在时间限制的迭代中连续调用基准方法,* 并计算我们执行该方法的次数来衡量原始吞吐量。我们正在使用特殊注解来选择要测量的单位,尽管你可以使用默认值。** 我根据我的理解还是说几句人话吧,他的意思是我们之前不是在案例1中输出的是吞吐量的测试指标吗,这里的意思是你可以* 使用@BenchmarkMode这个注解,里面设置参数Mode.Throughput一样可以是通过吞吐量的指标的,或者说你不设置,默认* 本身就是吞吐量,我们第一个案例就是默认的。* 所以我们在第一个方法上看到新出现的两个注解* @BenchmarkMode:设置计算指标* @OutputTimeUnit:计算模式对应的单位*/@Benchmark@BenchmarkMode(Mode.Throughput)@OutputTimeUnit(TimeUnit.SECONDS)public void measureThroughput() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.AverageTime measures the average execution time, and it does it* in the way similar to Mode.Throughput.* 在性能测试或基准测试的背景下,Mode.AverageTime(平均时间模式)测量了给定操作或代码片段的平均执行时间。* 该模式计算了每次调用被测试代码所花费的平均时间。它与Mode.Throughput(吞吐量模式)相似,两种模式都专注于性能测量,* 但它们在优先考虑的性能方面存在差异。以下是Mode.AverageTime和Mode.Throughput之间的简要比较:* 平均时间:该模式计算每个操作或调用的平均执行时间。它提供了关于单个操作平均执行时间的信息。* 吞吐量:另一方面,Mode.Throughput关注的是在给定时间内完成的操作速率。它衡量每单位时间内可以执行多少操作,通常是每秒。* 它提供了系统在高负载下处理大量操作的效率信息。* 虽然两种模式都提供了有关性能的有价值的信息,但它们服务于不同的目的,可能适用于不同类型的性能分析。* Mode.AverageTime适用于了解单个操作的平均延迟或执行时间,而Mode.Throughput更适用于在指定时间范围内最大化完成的操作数量。*** Some might say it is the reciprocal throughput, and it really is.* There are workloads where measuring times is more convenient though.* 有人说,这个指标是吞吐量的倒数,你也可以这么理解,不过有时候你测试的时候,统计时间维度是更加直观的。** 换言之,这个是统计你方法的执行平均时间的,所以看起来比吞吐量更加直观,毕竟耗时是我们普遍关心的第一指标*/@Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAvgTime() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.SampleTime samples the execution time. With this mode, we are* still running the method in a time-bound iteration, but instead of* measuring the total time, we measure the time spent in *some* of* the benchmark method calls.** Mode.SampleTime是用于对方法执行时间进行采样的一种模式。在这种模式下,我们仍然在一个有时间限制的迭代中运行方法,* 但不再测量总时间,而是测量一部分基准方法调用所花费的时间。使用Mode.SampleTime模式时,* 基准测试框架会定期中断方法的执行并记录经过的时间。通过只对部分调用进行采样,可以减少与连续时间测量相关的开销,* 同时仍能提供有关方法执行时间分布的有意义数据,而不仅仅关注整体持续时间。这种模式对于识别执行时间的变化非常有用,* 特别是如果方法的某些部分可能具有不同的性能特点或表现出间歇性行为。它使开发人员能够了解方法在不同条件下的性能表现,* 并帮助优化其性能。** This allows us to infer the distributions, percentiles, etc.* JMH also tries to auto-adjust sampling frequency: if the method* is long enough, you will end up capturing all the samples.* 这样可以让我们推断出分布情况、百分位数等。JMH 还会尝试自动调整采样频率:如果方法足够长,你最终会捕获到所有的样本** 这个解释的不明确,我们待会通过现象来看一下具体啥意思。*/@Benchmark@BenchmarkMode(Mode.SampleTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSamples() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Mode.SingleShotTime measures the single method invocation time. As the Javadoc* suggests, we do only the single benchmark method invocation. The iteration* time is meaningless in this mode: as soon as benchmark method stops, the* iteration is over.** Mode.SingleShotTime测量的是单个方法调用的时间。正如Javadoc所建议的,我们只进行一次基准方法的调用。* 在这种模式下,迭代时间是没有意义的:一旦基准方法停止,迭代就结束了。** This mode is useful to do cold startup tests, when you specifically* do not want to call the benchmark method continuously.* 这种模式在进行冷启动测试时非常有用,当你不想连续调用基准方法时。** 说白了就是只测试一次,就跟你跑main函数一样的,没有预热,就是冷启动的测试。*/@Benchmark@BenchmarkMode(Mode.SingleShotTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSingleShot() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** We can also ask for multiple benchmark modes at once. All the tests* above can be replaced with just a single test like this:** 这个注解还能写数组,指定多种测试指标,一起生效*/@Benchmark@BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureMultiple() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}/** Or even...* 如果你懒得写很多模式,你还能直接用Mode.All来表示全部的模式*/@Benchmark@BenchmarkMode(Mode.All)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAll() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

二、@BenchmarkMode

我们先不急着运行程序,我们在看完上面的例子之后可以看到这次出现了一个新的注解,就是
@BenchmarkMode

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BenchmarkMode {Mode[] value();
}

这个注解我们看到,作用的位置就是方法和类上面,你要是标注在类上,那就这个类所有的方法都按照这个配置生效了。
而且我们注意到他有一个变量,是Mode类型的数组,注意是数组,也就是可以传入多个。我们看一下这个Mode类型是啥。

public enum Mode {Throughput("thrpt", "Throughput, ops/time"),AverageTime("avgt", "Average time, time/op"),SampleTime("sample", "Sampling time"),SingleShotTime("ss", "Single shot invocation time"),All("all", "All benchmark modes");
}

就是个枚举类型,总共五个类型,我们上面的注释其实也标注了这五个类型的各自的作用。

三、 @OutputTimeUnit

与@BenchmarkMode 配套的还有一个注解就是@OutputTimeUnit。

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OutputTimeUnit {TimeUnit value();
}

他的作用就是你输出指标的时间单位,没别的了。OK,我们在大致有个了解之后,我们开始通过执行程序来看一下结果,加深我们对于注解的理解。

四、执行程序

鉴于我们这里这次一次写了N个方法测试,输出的报告巨长,我们这里就一个一个的测试,这样方便观察。

1、测试吞吐模式:measureThroughput

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.Throughput, as stated in its Javadoc, measures the raw throughput by* continuously calling the benchmark method in a time-bound iteration, and* counting how many times we executed the method.** We are using the special annotation to select the units to measure in,* although you can use the default.** AI直译:Mode.Throughput,如其Javadoc所述,通过在时间限制的迭代中连续调用基准方法,* 并计算我们执行该方法的次数来衡量原始吞吐量。我们正在使用特殊注解来选择要测量的单位,尽管你可以使用默认值。** 我根据我的理解还是说几句人话吧,他的意思是我们之前不是在案例1中输出的是吞吐量的测试指标吗,这里的意思是你可以* 使用@BenchmarkMode这个注解,里面设置参数Mode.Throughput一样可以是通过吞吐量的指标的,或者说你不设置,默认* 本身就是吞吐量,我们第一个案例就是默认的。* 所以我们在第一个方法上看到新出现的两个注解* @BenchmarkMode:设置计算指标* @OutputTimeUnit:计算模式对应的单位*/@Benchmark@BenchmarkMode(Mode.Throughput)@OutputTimeUnit(TimeUnit.SECONDS)public void measureThroughput() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

运行结果为:
Benchmark :JMHSample_02_01_BenchmarkModes.measureThroughput
Mode :thrpt
Cnt : 因为我控制了1次,所以这里没东西
Score :9.160 这个分数在吞吐这里其实就是你执行的吞吐量,因为我写的@OutputTimeUnit(TimeUnit.SECONDS)单位是秒,所以意思就是一秒能执行9.16次。
Error :没输出
Units:ops/s
我们看到这个吞吐量其实和我们在第一个案例测试的差不多,其实他就是默认的。你不写就是他。

2、测试平均时间模式:measureAvgTime

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.AverageTime measures the average execution time, and it does it* in the way similar to Mode.Throughput.* 在性能测试或基准测试的背景下,Mode.AverageTime(平均时间模式)测量了给定操作或代码片段的平均执行时间。* 该模式计算了每次调用被测试代码所花费的平均时间。它与Mode.Throughput(吞吐量模式)相似,两种模式都专注于性能测量,* 但它们在优先考虑的性能方面存在差异。以下是Mode.AverageTime和Mode.Throughput之间的简要比较:* 平均时间:该模式计算每个操作或调用的平均执行时间。它提供了关于单个操作平均执行时间的信息。* 吞吐量:另一方面,Mode.Throughput关注的是在给定时间内完成的操作速率。它衡量每单位时间内可以执行多少操作,通常是每秒。* 它提供了系统在高负载下处理大量操作的效率信息。* 虽然两种模式都提供了有关性能的有价值的信息,但它们服务于不同的目的,可能适用于不同类型的性能分析。* Mode.AverageTime适用于了解单个操作的平均延迟或执行时间,而Mode.Throughput更适用于在指定时间范围内最大化完成的操作数量。*** Some might say it is the reciprocal throughput, and it really is.* There are workloads where measuring times is more convenient though.* 有人说,这个指标是吞吐量的倒数,你也可以这么理解,不过有时候你测试的时候,统计时间维度是更加直观的。** 换言之,这个是统计你方法的执行平均时间的,所以看起来比吞吐量更加直观,毕竟耗时是我们普遍关心的第一指标*/@Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAvgTime() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

运行结果如下:
Benchmark :JMHSample_02_01_BenchmarkModes.measureAvgTime
Mode:avgt 平均统计模式
Cnt :同上
Score:108407.350
Error :没错误,不输出
Units:us/op 其实你能看出来,他是时间除以执行次数,所以就是吞吐量的倒数,吞吐量的意思是每秒能执行几次,这里就是执行一次需要几秒,不就是平均时间吗。只是我指定的时间单位是@OutputTimeUnit(TimeUnit.MICROSECONDS)微秒,所以这里自然也就是这个单位。
他主打的是一个平均耗时。

3、测试统计时间:measureSamples

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.SampleTime samples the execution time. With this mode, we are* still running the method in a time-bound iteration, but instead of* measuring the total time, we measure the time spent in *some* of* the benchmark method calls.** Mode.SampleTime是用于对方法执行时间进行采样的一种模式。在这种模式下,我们仍然在一个有时间限制的迭代中运行方法,* 但不再测量总时间,而是测量一部分基准方法调用所花费的时间。使用Mode.SampleTime模式时,* 基准测试框架会定期中断方法的执行并记录经过的时间。通过只对部分调用进行采样,可以减少与连续时间测量相关的开销,* 同时仍能提供有关方法执行时间分布的有意义数据,而不仅仅关注整体持续时间。这种模式对于识别执行时间的变化非常有用,* 特别是如果方法的某些部分可能具有不同的性能特点或表现出间歇性行为。它使开发人员能够了解方法在不同条件下的性能表现,* 并帮助优化其性能。** This allows us to infer the distributions, percentiles, etc.* JMH also tries to auto-adjust sampling frequency: if the method* is long enough, you will end up capturing all the samples.* 这样可以让我们推断出分布情况、百分位数等。JMH 还会尝试自动调整采样频率:如果方法足够长,你最终会捕获到所有的样本** 这个解释的不明确,我们待会通过现象来看一下具体啥意思。*/@Benchmark@BenchmarkMode(Mode.SampleTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSamples() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

在这里插入图片描述
他是以一种分布统计的方式输出的测试指标,单位还是平均时间耗时,等于说百分之99的测试跑一次是109707.264us的耗时,他内部给你做了一个测试,拆分出来测的,测出这么个结果来。
能看出来一个波动,和你实现的代码稳定性,而且他是抽样测试,不会都给你统计,比如我们设置的跑1轮,每轮一秒。可能这一秒跑了一万次,他不会像吞吐和平均那个样都算进去,他是一个抽样,可能抽了前面后面,没取中间。可能压根就是抽了前面。是一个分布统计。

4、测试只跑一次:measureSingleShot

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Mode.SingleShotTime measures the single method invocation time. As the Javadoc* suggests, we do only the single benchmark method invocation. The iteration* time is meaningless in this mode: as soon as benchmark method stops, the* iteration is over.** Mode.SingleShotTime测量的是单个方法调用的时间。正如Javadoc所建议的,我们只进行一次基准方法的调用。* 在这种模式下,迭代时间是没有意义的:一旦基准方法停止,迭代就结束了。** This mode is useful to do cold startup tests, when you specifically* do not want to call the benchmark method continuously.* 这种模式在进行冷启动测试时非常有用,当你不想连续调用基准方法时。** 说白了就是只测试一次,就跟你跑main函数一样的,没有预热,就是冷启动的测试。*/@Benchmark@BenchmarkMode(Mode.SingleShotTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureSingleShot() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

执行结果如下:
在这里插入图片描述
这就是测试冷启动的,没预热,就是直接跑,你也能看到单位是us/op。还是执行一次要多久。还是个平均值,只不过就是没预热直接开跑的。就跑一次。

5、测试多种模式组合:measureMultiple

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** We can also ask for multiple benchmark modes at once. All the tests* above can be replaced with just a single test like this:** 这个注解还能写数组,指定多种测试指标,一起生效*/@Benchmark@BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureMultiple() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

因为我们前面看了Mode是一个数组,所以可以传入多个模式。结果就是一起统计输出了。
在这里插入图片描述

6、测试全量模式:measureAll

package com.levi;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;// 预热注解,修改为只预热一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Warmup(iterations = 1,time = 1)
// 测试执行注解,修改为只执行一轮,每轮只跑一秒,默认是5,5这里改为1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {/** Or even...* 如果你懒得写很多模式,你还能直接用Mode.All来表示全部的模式*/@Benchmark@BenchmarkMode(Mode.All)@OutputTimeUnit(TimeUnit.MICROSECONDS)public void measureAll() throws InterruptedException {TimeUnit.MILLISECONDS.sleep(100);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(JMHSample_02_01_BenchmarkModes.class.getSimpleName()).forks(1).build();new Runner(opt).run();}
}

自然就是全部的统计都输出了:和上面一样。
在这里插入图片描述
你也可以看他的单位就知道他输出的计算方式了,次数除以时间,那就是平均时间的执行次数,就是吞吐。
时间除以次数,就是统计的某种模式下的平均时间。

五、总结

没啥总结的就是那两个注解,很详细了。

六、参考链接

1、JMH官方文档

这篇关于橘子学JDK之JMH-02(BenchmarkModes)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888150

相关文章

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus

mac jdk 1.7 dmg 官方版

百度云下载 https://pan.baidu.com/s/1SQiidrPFF5aZr4xlx0ekoQ https://pan.baidu.com/s/1SQiidrPFF5aZr4xlx0ekoQ   补充说明: 实际上oracle对于历史版本的jdk都有归档可以在官方网站上下载,只是需要注册个号就可以了。 地址如下: https://www.oracle.com/cn/java

MySQL record 02 part

查看已建数据库的基本信息: show CREATE DATABASE mydb; 注意,是DATABASE 不是 DATABASEs, 命令成功执行后,回显的信息有: CREATE DATABASE mydb /*!40100 DEFAULT CHARACTER SET utf8mb3 / /!80016 DEFAULT ENCRYPTION=‘N’ / CREATE DATABASE myd

配置Java(JDK)环境变量

一、配置JDK环境变量 将JDK-22压缩包加压缩到指定目录下面,本机路径是:C:\Program Files\Java(可以加压缩到自己的指定路径,记住这个路径,配置环境变量时候要使用)。 鼠标右键“此电脑”,点击“属性”,点击“高级系统设置”,然后进入“环境变量”。 点击“新建”,然后变量名填“JAVA_HOME”,变量值填自己的JDK的下载路径,我这里是“C:\\P

GPU 计算 CMPS224 2021 学习笔记 02

并行类型 (1)任务并行 (2)数据并行 CPU & GPU CPU和GPU拥有相互独立的内存空间,需要在两者之间相互传输数据。 (1)分配GPU内存 (2)将CPU上的数据复制到GPU上 (3)在GPU上对数据进行计算操作 (4)将计算结果从GPU复制到CPU上 (5)释放GPU内存 CUDA内存管理API (1)分配内存 cudaErro

docker学习系列(四)制作基础的base项目镜像--jdk+tomcat

前面已经完成了docker的安装以及使用,现在我们要将自己的javaweb项目与docker结合 1.1准备jdk+tomcat软件 ​​我下载了apache-tomcat-7.0.68.tar.gz和jdk-7u79-linux-x64.tar.gz,存储于Linux机器的本地目录/usr/ect/wt/下(利用xshell上传)。利用linux命令 tar -zxvf apache-tom

滚雪球学MyBatis(02):环境搭建

环境搭建 前言 欢迎回到我们的MyBatis系列教程。在上一期中,我们详细介绍了MyBatis的基本概念、特点以及它与其他ORM框架的对比。通过这些内容,大家应该对MyBatis有了初步的了解。今天,我们将从理论走向实践,开始搭建MyBatis的开发环境。了解并掌握环境搭建是使用MyBatis的第一步,也是至关重要的一步。 环境搭建步骤 在开始之前,我们需要准备一些必要的工具和软件,包括J

SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)

上一章讲了 BAPI的概念,以及如何调用SAP里面的既存BAPI。 SAP学习笔记 - 开发01 - BAPI是什么?通过界面和ABAP代码来调用BAPI-CSDN博客 本章继续讲开发相关的内容,主要就是BTP的实际操作流程,比如账号注册,登录,BTP集成开发环境的搭建这方面。 目录 1,账号注册 2,BTP登录URL 3,如何在BTP上进行开发? 以下是详细内容。 1,账

JVM、JRE和 JDK:理解Java开发的三大核心组件

Java是一门跨平台的编程语言,它的成功离不开背后强大的运行环境与开发工具的支持。在Java的生态中,JVM(Java虚拟机)、JRE(Java运行时环境)和JDK(Java开发工具包)是三个至关重要的核心组件。本文将探讨JVM、JDK和JRE的区别,帮助你更好地理解Java的运行机制。 1. JVM:Java虚拟机(Java Virtual Machine) 什么是JVM? JVM,即