前言

上一篇主要从整体架构上概括了Java的内存结构,只是在宏观上有一个大体的认识,不够深入,接下来这篇文章,将进一步深入探究Java的内存结构模型,作为上一篇的补充。

正文

接下来,结合两个示例代码来深入探究Java 的内存结构,
示例代码1:

/*** VM参数* -Xms30m                     设置堆内存最小值为30M* -Xmx30m                     设置堆内存最大值为30M* -XX:MaxMetaspaceSize=30m    设置元空间最大值为30M* -XX:+UseConcMarkSweepGC     启用CMS垃圾收集器* -XX:-UseCompressedOops      禁用压缩指针的使用*/
public class JVMObject {public final static String MAN_TYPE = "man"; // 常量public static String WOMAN_TYPE = "woman";  // 静态变量public static void  main(String[] args)throws Exception {Teacher T1 = new Teacher();T1.setName("Mark");T1.setSexType(MAN_TYPE);T1.setAge(36);for(int i =0 ;i<15 ;i++){System.gc();//主动触发GC 垃圾回收 15次--- T1存活}Teacher T2 = new Teacher();T2.setName("King");T2.setSexType(MAN_TYPE);T2.setAge(18);Thread.sleep(Integer.MAX_VALUE);//线程休眠}
}class Teacher{String name;String sexType;int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSexType() {return sexType;}public void setSexType(String sexType) {this.sexType = sexType;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

示例代码2:

public class JVMStack {public int work(int x) throws Exception{int z =(x+5)*10;//局部变量表有, 32位Thread.sleep(Integer.MAX_VALUE);return  z;}public static void main(String[] args)throws Exception {JVMStack jvmStack = new JVMStack();jvmStack.work(10);//10  放入main栈帧  10 ->操作数栈}
}

一、JVM的运行流程

加入VM参数

 -Xms30m -Xmx30m  -XX:MaxMetaspaceSize=30m  -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops

在这里插入图片描述
启动示例代码1
在这里插入图片描述
上述代码的执行过程中,JVM具体做了哪些工作呢?
1. JVM 向操作系统申请内存
JVM 第一步就是通过配置参数或者默认配置参数向操作系统申请内存空间,操作系统根据内存大小找到具体的内存分配表,然后把内存段的起始地址和终止地址分配给 JVM,接下来 JVM 就进行内部分配。
2. 初始化运行时数据区
JVM 获得内存空间后,会根据配置参数分配堆、栈以及方法区的内存大小
-Xms30m -Xmx30m -Xss1m -XX:MaxMetaspaceSize=30m
在这里插入图片描述
3. 类加载(类加载的细节后续章节会详细讲)
这里主要是把 class 放入方法区、还有 class 中的静态变量和常量也要放入方法区
在这里插入图片描述
4. 执行方法及创建对象
启动 main 线程,执行 main 方法,开始执行第一行代码。此时堆内存中会创建一个 Teacher对象,对象引用 T1 就存放在栈中。后续代码中遇到 new 关键字,会再创建一个 Teacher对象,对象引用T2 就存放在栈中。
在这里插入图片描述

小结

JVM 在操作系统上启动,申请内存,先进行运行时数据区的初始化,然后把类加载到方法区,最后执行方法。方法的执行和退出过程在内存上的体现就是虚拟机栈中栈帧的入栈和出栈。同时在方法的执行过程中创建的对象一般情况下都是放在堆中,最后堆中的对象也是需要进行垃圾回收清理的。

二、从底层深入理解运行时数据区

1、堆空间分代划分

堆被划分为新生代和老年代(Tenured),新生代又被进一步划分为 Eden 和 Survivor 区,最后 Survivor 由 From Survivor 和 To Survivor 组成。(先有个概念,后续对象分配和垃圾回收会细讲这块)
在这里插入图片描述

GC概念

GC- Garbage Collection 垃圾回收,在 JVM 中是自动化的垃圾回收机制,我们一般不用去关注,在 JVM 中 GC 的主要区域是堆空间
我们也可以通过一些额外方式主动发起它,比如 System.gc(),主动发起。(项目中切记不要使用,严重影响性能

2、JHSDB ——内存可视化工具

JHSDB 是一款基于服务性代理实现的进程外调试工具。服务性代理是 HotSpot 虚拟机中一组用于映射 Java 虚拟机运行信息的,主要基于 Java 语言实现的API 集合。

2.1 JHSDB的开启方式

  • JDK1.8 中的开启方式
    (1)首先需将 sawindbg.dll(一般会在 JDK自带的jre 目录下)复制到安装的jre 的对应目录中 (注意在 win 上安装了 JDK1.8 后往往同级目录下有一个jre 的目录)
    在这里插入图片描述
    (2)然后到目录:D:\Java\jdk1.8.0_112\lib 进入命令行,执行 java -cp .\sa-jdi.jar sun.jvm.hotspot.HSDB
    在这里插入图片描述
  • JDK1.9 及以后的开启方式
    进入 JDK 的 bin 目录下,我们可以在命令行中使用 jhsdb hsdb 来启动它

2.2 JHSDB中查看堆信息

  1. 启动示例代码1
    在这里插入图片描述
  2. 因为 JVM 启动有一个进程,需要借助一个命令 jps 查找到对应程序的进程
    在这里插入图片描述
  3. 在JHSDB中依次点击File->Attach to HotSpot process,在弹出的界面中输入要查看的类的进程ID
    在这里插入图片描述
    在这里插入图片描述
  4. 查看堆参数
    在这里插入图片描述
    图中显示了实际 JVM 启动过程中堆中参数的对照,可以看到,在不启动内存压缩的情况下。堆空间里面的分代划分都是连续的。
  5. 查看堆中对象
    在这里插入图片描述
    这里可以看到 JVM 中所有的对象,都是基于 class 的对象,可以在这里进行全路劲名搜索自己想查看的对象。
    在这里插入图片描述
    最后再对比一下内存地址可以得出 T1 在老年代,T2 在 Eden,如图所示
    在这里插入图片描述
    在这里插入图片描述

2.3 JHSDB中查看栈信息

  • 选中要查看的线程 ,点击 Stack Memory 按钮
    在这里插入图片描述
    在这里插入图片描述
    从上图中可以验证栈内存,同时也可以验证到虚拟机栈和本地方法栈在 Hotspot 中是合二为一的实现了。

3、小结

深入辨析堆和栈

  • 功能
    栈内存以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char 等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放;
    堆内存用来存储 Java 中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;
  • 线程独享还是共享
    栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
    堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
  • 空间大小
    栈的内存要远远小于堆内存

三、虚拟机栈的优化技术——栈帧之间的数据共享

在一般的模型中,两个不同的栈帧的内存区域是独立的,但是大部分的 JVM 在实现中会进行一些优化,使得两个栈帧出现一部分重叠。(主要体现在方法中有参数传递的情况),让下面栈帧的操作数栈和上面栈帧的部分局部变量重叠在一起,这样做不但节约了一部分空间,更加重要的是在进行方法调用时就可以直接公用一部分数据,无需进行额外的参数复制传递了。
在这里插入图片描述
下面通过JHSDB来查看栈帧之间的数据共享

  • 运行示例代码2
    在这里插入图片描述
  • 在JHSDB查看栈信息
    在这里插入图片描述
public class JVMStack {public int work(int x) throws Exception{int z =(x+5)*10;//局部变量表有, 32位Thread.sleep(Integer.MAX_VALUE);return  z;}public static void main(String[] args)throws Exception {JVMStack jvmStack = new JVMStack();jvmStack.work(10);//10  放入main栈帧  10 ->操作数栈}
  • 代码分析
    栈帧之间的数据共享,就是物理上的同一块内存区域,在JVM的逻辑中被虚拟成两块或更多块的内存区域,比如main方法中的work(10)中的 10 在jvm中是存放在main方法栈帧的操作数栈,而work(int x)中的 x 在jvm中是存放在work方法栈帧的局部变量表,但他们的真实内存地址是同一块,因此 x==10,从而实现了栈帧之间的数据共享

四、内存溢出

1、栈溢出

HotSpot 版本中栈的大小是固定的,是不支持拓展的。
java.lang.StackOverflowError 一般的方法调用是很难出现的,如果出现了可能会是无限递归。
虚拟机栈带给我们的启示:方法的执行因为要打包成栈桢,所以天生要比实现同样功能的循环慢,所以树的遍历算法中:递归和非递归(循环来实现)都有存在的意义。递归代码简洁,非递归代码复杂但是速度较快。
OutOfMemoryError:不断建立线程,JVM 申请栈内存,机器没有足够的内存。
同时要注意,栈区的空间 JVM 没有办法去限制的,因为 JVM 在运行过程中会有线程不断的运行,没办法限制,所以只限制单个虚拟机栈的大小。

示例代码

/*** 栈溢出  -Xss=1m*/
public class StackOverFlow {public void king(){//方法不断执行-栈帧不断入栈(不出栈)king();//}public static void main(String[] args)throws Throwable {StackOverFlow javaStack = new StackOverFlow();javaStack.king();}
}

2、堆溢出

内存溢出:申请内存空间,超出最大堆内存空间。
如果是栈内存溢出,则通过调大 -Xms,-Xmx 参数。
如果不是栈内存泄漏,就是说内存中的对象确实都是必须存活的,那么就应该检查 JVM 的堆参数设置,与机器的内存对比,看是否还有可以调整的空间,再从代码上检查是否存在某些对象生命周期过长、持有状态时间过长、存储结构设计不合理等情况,尽量减少程序运行时的内存消耗。

示例代码1

/*** VM Args:-Xms30m -Xmx30m -XX:+PrintGCDetails* 堆内存溢出(直接溢出)*/
public class HeapOom {public static void main(String[] args){String[] strings = new String[35*1000*1000];  //35m的数组(堆)}
}

示例代码2

/*** VM Args:-Xms30m -Xmx30m     堆的大小30M* 造成一个堆内存溢出(分析下JVM的分代收集)* GC调优---生产服务器推荐开启(默认是关闭的)* -XX:+HeapDumpOnOutOfMemoryError*/
public class HeapOom2 {public static void main(String[] args) throws Exception {List<Object> list = new LinkedList<>(); // list   当前虚拟机栈(局部变量表)中引用的对象int i =0;while(true){i++;if(i%1000==0) Thread.sleep(10);list.add(new Object());// 不能回收2,  优先回收再来抛出异常。}}
}

3、方法区溢出

  • 运行时常量池溢出
  • 方法区中保存的 Class 对象没有被及时回收掉或者 Class 信息占用的内存超过了我们配置的大小。
    注意 Class 要被回收,条件比较苛刻(仅仅是可以,不代表必然,因为还有一些参数可以进行控制):
    1、该类所有的实例都已经被回收,也就是堆中不存在该类的任何实例。
    2、 加载该类的 ClassLoader 已经被回收。
    3、 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

示例代码:

/*** 方法区导致的内存溢出* VM Args: -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M* */
public class MethodAreaOutOfMemory {public static void main(String[] args) {while (true) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(TestObject.class);enhancer.setUseCache(false);enhancer.setCallback(new MethodInterceptor() {public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {return arg3.invokeSuper(arg0, arg2);}});enhancer.create();}}public static class TestObject {private double a = 34.53;private Integer b = 9999999;}
}

cglib 是一个强大的,高性能,高质量的 Code 生成类库,它可以在运行期扩展 Java 类与实现 Java 接口。CGLIB 包的底层是通过使用一个小而快的字节码处理框架 ASM,来转换字节码并生成新的类。除了 CGLIB 包,脚本语言例如 Groovy 和 BeanShell,也是使用 ASM 来生成 java 的字节码。当然不鼓励直接使用 ASM,因为它要求你必须对 JVM 内部结构包括 class 文件的格式和指令集都很熟悉。

4、直接内存溢出

直接内存的容量可以通过 MaxDirectMemorySize 来设置(默认与堆内存最大值一样),所以也会出现 OOM 异常;由直接内存导致的内存溢出,一个比较明显的特征是在 HeapDump 文件中不会看见有什么明显的异常情况,如果发生了 OOM,同时 Dump 文件很小,可以考虑重点排查下直接内存方面的原因。

示例代码

/*** 启动前先设置以下VM参数* VM Args:-XX:MaxDirectMemorySize=100m* 限制最大直接内存大小100m*/
public class DirectOom {public static void main(String[] args) {//直接分配128M的直接内存ByteBuffer bb = ByteBuffer.allocateDirect(128*1024*1204);}
}

五、常量池

1、class常量池(静态常量池)

在 class 文件中除了有类的版本、字段、方法和接口等描述信息外,还有一项信息是常量池 (Constant Pool Table),用于存放编译期间生成的各种字面量符号引用
在这里插入图片描述

  • 字面量
    给基本类型变量赋值的方式就叫做字面量或者字面值。
    比如:String a=“b” ,这里“b”就是字符串字面量,同样类推还有整数字面值、浮点类型字面量、字符字面量。
  • 符号引用
    符号引用以一组符号来描述所引用的目标。符号引用可以是任何形式的字面量,JAVA 在编译的时候每个 java 类都会被编译成一个 class文件,但在编译的时候虚拟机并不知道所引用类的地址(实际地址),就用符号引用来代替,而在类的解析阶段(后续 JVM 类加载会具体讲到)就是为了把这个符号引用转化成为真正的地址的阶段。
    一个 java 类(假设为 People 类)被编译成一个 class 文件时,如果 People 类引用了 Tool 类,但是在编译时 People 类并不知道引用类的实际内存地址,因此只能使用符号引用(org.simple.Tool)来代替。而在类装载器装载 People 类时,此时可以通过虚拟机获取 Tool 类的实际内存地址,因此便可以将符号org.simple.Tool 替换为 Tool 类的实际内存地址。

2、运行时常量池

虚拟机规范中的描述:

运行时常量池(Runtime Constant Pool)是每一个类或接口的常量池(Constant_Pool)的运行时表示形式,它包括了若干种不同的常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。

运行时常量池是在类加载完成之后,将 Class 常量池中的符号引用值转存到运行时常量池中,类在解析之后,将符号引用替换成直接引用。
运行时常量池在 JDK1.7 版本之后,就移到堆内存中了,这里指的是物理空间,而逻辑上还是属于方法区(方法区是逻辑分区)。
在 JDK1.8 中,使用元空间代替永久代来实现方法区,但是方法区并没有改变,所谓"Your father will always be your father"。变动的只是方法区中内容的物理存放位置,比如运行时常量池和字符串常量池被移动到了堆中(物理上),但是逻辑上它们还是属于方法区的。

3、字符串常量池

字符串常量池这个概念是最有争议的,翻阅了虚拟机规范等很多正式文档,发现没有这个概念的官方定义,我们可从它的作用和 JVM 设计它用于解决什么问题的点来分析它。以 JDK1.8 为例,字符串常量池是存放在堆中,并且与 java.lang.String 类有很大关系。设计这块内存区域的原因在于:String 对象作为 Java数据类型,被使用的频率是最高的,在内存中占据空间也是最大的,因此高效地使用字符串,可以提升系统的整体性能。所以要彻底弄懂字符串常量池,我们的重心其实在于深入理解 String。

六、深入理解String

1、String 类的源码解读(JDK1.8)

通过阅读String源码,我们发现String内部维护的是一个被final修饰的char数组,主要包含两个成员变量:value[](char数组)hash(用来存放hash值)
在这里插入图片描述

String 对象的不可变性

通过源码我们还发现 String 类被 final 关键字修饰了,而且变量 char 数组也被 final 修饰了。
我们知道类被 final 修饰代表该类不可继承,而 char[]被 final+private 修饰,代表了 String 对象不可被更改。Java 实现的这个特性叫作 String 对象的不可变性,即 String 对象一旦创建成功,就不能再对它进行改变。
Java 这样做的好处在哪里呢?

 1. 保证 String 对象的安全性。假设 String 对象是可变的,那么 String 对象将可能被恶意修改。2. 保证 hash 属性值不会频繁变更,确保了唯一性,使得类似 HashMap 容器才能实现相应的 key-value 缓存功能。3. 可以实现字符串常量池。在 Java 中,通常有两种创建字符串对象的方式,一种是通过字符串常量的方式创建,如 String   str=“abc”;另一种是字符串变量通过 new 形式的创建,如 String str = new String(“abc”)

2、String 的创建方式及内存分配的方式

方式1:String str=“abc”;

当代码中使用这种方式创建字符串对象时,JVM 首先会检查该对象是否在字符串常量池中,如果存在,就返回该对象引用,否则新的字符串将在常量池中被创建。这种方式可以减少同一个值的字符串对象的重复创建,节约内存。(str 只是一个引用)
String str=“abc的内存分配方式

方式2:String str = new String(“abc”)

首先在编译类文件时,"abc"常量字符串将会放入到常量结构中,在类加载时,“abc"将会在字符串常量池中创建;其次,在调用 new 时,JVM 命令将会调用 String的构造函数,同时引用字符串常量池中的"abc” 字符串,在堆内存中创建一个 String 对象;最后,str 将引用 String 对象。
在这里插入图片描述
使用 new,对象会创建在堆中,同时赋值的话,会在常量池中创建一个字符串对象并复制到堆中。
具体的复制过程是先将常量池中的字符串压入栈中,在使用 String 的构造方法是,会拿到栈中的字符串作为构造方法的参数。这个构造函数是一个 char 数组的赋值过程,而不是 new 出来的,所以是引用了常量池中的字符串对象。存在引用关系。

方式3:String str2= “ab”+ “cd”+ “ef”;

编程过程中,字符串的拼接很常见。前面我讲过 String 对象是不可变的,如果我们使用 String 对象相加,拼接我们想要的字符串,是不是就会产生多个对象呢?例如以下代码:

String str= "ab"+ "cd"+ "ef";

理论上这段代码会创建3个对象:首先会生成 ab 对象,再生成 abcd 对象,最后生成 abcdef 对象,非常低效。
实际上,为了提高效率,编译器自动优化了这行代码,编译后的代码,如下

String str= "abcdef";

3、intern方法实战

JDK 1.7后,intern方法会先去查询常量池中是否存在与本对象(调用intern方法的对象)值相同的其他对象或对象引用(判断引用的依据是对象的值相同),如果存在,则返回常量池中的对象或引用,如果不存在,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。
在这里插入图片描述
几张图轻松理解String.intern()

下面通过几个案例来深入解读String.intern()方法

案例1

示例代码

/**1. 测试String.intern()方法的用法*/
public class TestIntern {public static void main(String[] args){String s2 = new String("ja")+new String("va01");//只在堆中创建了String("java")对象,并未在常量池中创建"java"字符串常量s2.intern();String s3 = new String("java01");s3.intern();String s1 = "java01";//这里的"java"并不是常量池中的字符串常量对象,而是常量池中的引用System.out.println(s2==s1);System.out.println(s2=="java01");System.out.println(s3==s1);System.out.println(s3=="java01");System.out.println(s3.intern()==s2);}
}

运行结果

true
true
false
false
true

结果解析

  1. String s2 = new String(“ja”)+new String(“va01”);
    这行代码只在堆中创建了String(“java01”)对象(用A表示),并未在常量池中创建"java"字符串常量
    在这里插入图片描述

  2. s2.intern();
    常量池中不存在,所以会在常量池中生成一个原对象的引用,并返回该引用
    在这里插入图片描述

  3. String s3 = new String(“java01”);
    在堆中创建一个String(“java”)对象(用B表示),并把常量池中引用Y指向的对象的值赋给对象B的的value
    在这里插入图片描述

  4. s3.intern();
    因为常量池中存在引用Y,所以不会再创建,而是直接返回引用
    在这里插入图片描述

  5. String s1 = “java01”;
    因为常量池中已存在引用Y,所以直接将引用Y赋值给s1
    在这里插入图片描述
    终上所述,结果显而易见

后语

本系列文章皆是笔者对所学的归纳总结,由于本人学识有限,如有错误之处,望各位看官指正

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. java工厂模式

    本文转载截取,原文内容更丰富。想详细了解的小伙伴可以去原创作者: https://blog.csdn.net/zhangerqing/article/details/8194653 工厂方法模式(Factory Method) 工厂方法模式分为四种: 1、普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。首…...

    2024/4/28 3:23:26
  2. 正则表达式使用方法和re模块中常用的方法

    正则表达式 在python里使用正则表达式,需要导入 re模块中的fullmatch from re import fullmatch使用方法: fullmatch(正则表达式,字符串) - 判断正则表达式和字符串是否匹配,如果不能匹配返回None普通字符字符 含义. 匹配一个任意字符\w 匹配任意一个数字、字母或者下划线…...

    2024/5/2 18:02:29
  3. (精华)2020年8月7日 微信小程序 音频文件的使用

    旧版 <!-- audio.wxml --> <audio poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop></audio><button type="primary" bindtap="a…...

    2024/5/2 14:38:46
  4. springboot+jwt实现token认证

    首先编写拦截器,拦截请求 @Component public class LoginInterceptor implements HandlerInterceptor {/*** 在请求被处理之前调用* @param request* @param response* @param handler* @return*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletR…...

    2024/4/25 1:41:59
  5. vscode vetur eslint 代码自动格式化

    自己整理的最简配置 {"workbench.iconTheme": "vscode-icons", // 图标插件:搜索vscode-icons安装"editor.formatOnSave": true, // 保存时自动格式化"[vue]": { // .vue文件使用vetur作为格式化工具"editor.defaultFormatter&q…...

    2024/5/2 11:48:49
  6. 排序(Sort)

    排序1、 排序的基本知识2、 插入类排序2.1 直接插入排序2.2 折半插入排序2.3 希尔排序3、 交换类排序3.1 冒泡排序3.2 快速排序4、 选择类排序4.1 简单选择排序4.2 堆排序5、 归并排序6、 基数排序7、 内部排序归纳总结7.1 复杂度比较7.2 如何选择排序7.3 稳定性8、 外部排序8.…...

    2024/4/15 20:48:14
  7. 5007.jsoncpp库编程

    jsoncpp 库的使用.//2.测试一下jsoncpp库是否好使.Json::Value root;Json::Value data;root["action"] = "run";data["number"] = 1;root["data"] = data;Json::FastWriter writer;std::string json_str = writer.write(root);RCLCPP_…...

    2024/4/15 20:48:13
  8. 懒加及thymeleaf

    懒加载懒加载即按需加载,当页面需要时再加载处理,以减少本地缓存的压力。懒加载的原理:页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片,只有通过javascript设置了图片路径,浏览器才会发送请求。 懒加载的原理就是先在页面中把所有的图片统一使用一张占…...

    2024/4/15 20:48:13
  9. 微服务架构设计模式 读书笔记一

    作者:[美] 克里斯理查森(Chris Richardson) 是Java社区的著名布道师、JavaOne等知名技术大会的常年主讲人,也是《POJOs in Action》(中文名《用轻量级框架开发企业应用》)一书的作者。 微服务领域公认的思想领袖,并定期在国际会议上发表演讲。 https://microservices.i…...

    2024/4/15 20:48:13
  10. C3P0连接池详细配置

    <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement">3</property> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 3…...

    2024/5/2 16:27:08
  11. GDI+ 保存HDC为位图文件

    //GDI+为图片的加载、存储,屏蔽了内部编解码、压缩解压缩等的具体细节,给程序员带来了极大的方便 //目前版本的GDI+支持bmp jpeg gif tiff png等几种格式 //下面的程序基本思路是先将目标DC上的内容存到内存BITMAP //再使用GDI+Bitmap::FromHBITMAP加载内存位图,并保存…...

    2024/4/15 20:48:11
  12. 【萌新的Java Web开发学习笔记】第五章 MVC

    JavaWEB MVC写Java Web项目时会发现,一个中型或者大型项目 随着代码的增多,会发现:代码既可以写在src目录下,也可以写在WebContent目录下。src下可以建很多包 ,WebContent下可以建很多文件夹。所以问题就来了:一个新的类 到底往哪个目录下的哪个文件夹里写?此时解决办法…...

    2024/4/23 9:34:19
  13. LeetCode 283.移动零

    移动零 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 说明:必须在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数。思路:循环数组,跳过数组元素为零的,并将非零的元素放在原数组中,末尾元素补零。 #include <stdio.…...

    2024/5/2 9:32:51
  14. [Swift 开发] &&和||运算符优先级

    print(true || false && false) print((true || false) && false) print(true || (false && false))第一行:看不出谁的运算级谁高 第二行:把||用括号括起来,增强或优先级 第三行:把&&用括号括起来,增强与优先级根据第二行和第三行的输出…...

    2024/4/15 20:48:07
  15. 微积分(六)——一元函数微分学

    文章目录前言(一)一元函数微分学基础1)讨论导数与微分的概念2)导数与微分的计算(二)导数的应用1)通过导数定义的属性2)通过导数计算的属性3)与导数间接相关的属性4)函数的应用题(多为最值问题)(三)中值定理1)不等式问题a. 具体函数不等式问题b. 抽象函数不等式问题2)…...

    2024/4/15 20:48:07
  16. jQuery动画内容

    jQuery动画 1、jQuery隐藏显示 可以使用hide()和show()方法来隐藏和显示HTML元素。不占位置 本质是在行内样式表中添加了display:none样式。 $("#hide").click(function(){ $("p").hide(); }); $("#show").click(function(){ $("p").s…...

    2024/4/16 20:55:59
  17. JAVA Map<String,Object> 与xml的转换

    1、map-->xml/*** @将Dictionary转成xml* @return 经转换得到的xml串**/public static String toXml(Map<String,Object> parm){StringBuffer xml = new StringBuffer();xml.append("<xml>");if(parm != null){for (Map.Entry<String, Object> …...

    2024/4/15 20:48:03
  18. win10 jenkins unity android设置

    Manage Jenkins -> Configure System -> Global properties添加Environment variablesANDROID_NDK_ROOTANDROID_SDK_ROOTGRADLE_USER_HOME -> C:\Users\Administrator\.gradle...

    2024/4/25 9:36:30
  19. 数学基础

    一、中心极限定理 简介 总体数据A(任意分布,不要求正态分布) 从A中随机抽取n个样本组成B 抽取m次,得到m组B 所有B的平均值的分布接近正态分布 注意:总体数据不要求正态分布 样本每组足够大,但也不需要太大额:所有B的平均值的平均值能够反映A的平均值...

    2024/4/15 13:24:21
  20. 第5章-7 列表去重 (40分)【Python版本】

    输入一个列表,去掉列表中重复的数字,按原来次序输出!输入格式:在一行中输入列表输出格式:在一行中输出不重复列表元素输入样例:在这里给出一组输入。例如:[4,7,5,6,8,6,9,5] 输出样例:在这里给出相应的输出。例如:4 7 5 6 8 9【Python参考代码】#By yangbo 2020.8.07 lst …...

    2024/4/15 13:24:19

最新文章

  1. 纯血鸿蒙APP实战开发——主页瀑布流实现

    介绍 本示例介绍使用ArkUIWaterFlow组件和LazyForEach实现瀑布流场景。该场景多用于购物、资讯类应用。 效果图预览 使用说明 加载完成后显示整个列表&#xff0c;超过一屏时可以上下滑动。 实现思路 创建WaterFlowDataSource类&#xff0c;实现IDataSource接口的对象&…...

    2024/5/2 19:46:59
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. jQuery(一)

    文章目录 1. 基本介绍2.原理示意图3.快速入门1.下载jQuery2.创建文件夹&#xff0c;放入jQuery3.引入jQuery4.代码实例 4.jQuery对象与DOM对象转换1.基本介绍2.dom对象转换JQuery对象3.JQuery对象转换dom对象4.jQuery对象获取数据获取value使用val&#xff08;&#xff09;获取…...

    2024/5/1 13:36:17
  4. 微信小程序生命周期管理:从数据初始化到事件绑定

    作为一个独立的应用开发平台,微信小程序提供了自己的生命周期机制,与我们熟悉的Vue.js框架有一些差异。掌握小程序生命周期的特点和使用技巧,对于开发高质量的小程序应用至关重要。深入理解和掌握小程序生命周期的使用技巧,将有助于我们构建出更加健壮和可维护的小程序应用。 小…...

    2024/4/30 14:39:15
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/2 11:19:01
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/2 16:04:58
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/1 21:18:12
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/2 9:47:31
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/2 9:47:31
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/2 6:03:07
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/2 9:47:30
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/1 11:24:00
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/2 5:31:39
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/1 20:22:59
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/2 9:47:28
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/2 9:47:27
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/2 0:07:22
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/2 8:37:00
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/2 9:47:26
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/2 9:47:25
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/1 14:33:22
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/2 18:46:52
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/2 7:30:11
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/1 20:56:20
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57