开发小记~

IDEA

IEDA卡顿

原因1 :划分的内存空间太小
工具栏 下 help -> Edit custom VM options
在这里插入图片描述
如果初始内存和最大内存都设置的太小,可能会出现打不开IDEA的情况;
在这里插入图片描述
找到此路径下的vmoptions文件 再次修改保存重启IDEA即可

清空es数据

curl -XPOST 'http://localhost:9200/vops_original_asset_v1/_delete_by_query?conflicts=proceed' -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": {}
  }
}'

redis

连接失败问题

  1. RedisMessageListenerContainer : Connection failure occurred. Restarting subscription task after 5000 ms
    – 解决方式 : 检查项目中的和redis.conf中是否都配置了密码

elasticsearch配置问题

跨域无法访问问题

配置network.host 为 0.0.0.0

network.host: 0.0.0.0

elasticsearch-head连接不上

http.cors.enabled: true
http.cors.allow-origin: "*"

linux 命令

压缩

在 Linux 中,有许多种文件压缩格式,如 .tar、.gz、.bz2 和 .zip 等等。使用不同的压缩格式和算法,可以获得不同的压缩比和性能。因此,在使用压缩命令时,需要指定压缩格式和参数,以确保压缩结果符合预期。

下面是常见的压缩命令和参数:

tar 命令:
-c:创建新的压缩文件。
-v:显示压缩进度和文件列表。
-f:指定压缩文件的名称和路径。
-z:使用 gzip 算法进行压缩。
-j:使用 bzip2 算法进行压缩。
例如,要将 /path/to/folder 目录压缩成一个 .tar 文件并使用 gzip 算法压缩,可以使用以下命令:

tar -czvf package.tar.gz /path/to/folder/

要压缩当前目录(即当前所在路径)的所有文件和子目录,您可以使用 tar 命令来完成。下面是一个压缩成 .tar.gz 格式的示例:

tar -czvf archive.tar.gz .

只想压缩成 tar包可以去掉z

tar -cvf archive.tar .

解压缩

在 Linux 中,解压缩安装包的命令通常是 tar 命令。具体的命令参数可能因安装包的格式和压缩算法而异,下面列出一些常见的例子:

解压 .tar 格式的包: tar -xvf package.tar

解压 .gz 格式的包: tar -zxvf package.tar.gz

解压 .bz2 格式的包: tar -jxvf package.tar.bz2

解压 .zip 格式的包: unzip package.zip

内存

查看看内存使用情况 free -h

free -h 是一个 Linux 系统下的命令,用于显示系统内存使用情况。其中 -h 表示以人类可读的方式显示内存大小,即将内存大小转换为易于理解的单位,例如 KB、MB、GB 等。

当在终端中输入 free -h 命令后,会显示系统的内存使用情况,包括:

  • total:系统的物理内存总量
  • used:已经使用的物理内存大小
  • free:未被使用的物理内存大小
  • shared:被多个进程共享的物理内存大小
  • buffers:用于缓存数据的物理内存大小
  • cached:用于缓存文件的物理内存大小

示例输出:

              total        used        free      shared  buff/cache   available
Mem:           7.8G        1.4G        4.9G        128M        1.5G        6.0G
Swap:            0B          0B          0B

其中,Mem 表示系统物理内存的使用情况,Swap 表示系统交换分区的使用情况

拓展 --什么是swap区?

swap 是指 Linux 系统中的交换分区(Swap Partition)。交换分区是一种虚拟内存技术,用于在系统内存不足时,将一部分内存中的数据(通常是不常用的数据)交换到硬盘上,以释放出内存空间,从而避免出现内存不足的情况

在 Linux 系统中,交换分区通常是指一个硬盘分区,用于存储被交换出的内存数据。当系统需要更多的内存时,就会将一部分内存数据(包括未使用的内存和不常用的内存数据)交换到交换分区中,从而释放出更多的内存供系统使用。

防火墙

VOPS 防火墙列表路径
/etc/sysconfig
vim iptables

4.1 查看防火墙状态命令
1) systemctl status firewalld
2) firewall-cmd --state
4.2 关闭防火墙命令
1)临时性关闭(重启后失效): systemctl stop firewalld
2) 永久性关闭(重启后生效): systemctl disable firewalld
4.3 开启防火墙命令
1)临时性开启(重启后失效): systemctl start firewalld
2) 永久性开启(重启后生效): systemctl enable firewalld

第二种:
service iptables status
service iptables stop
service iptables start
永久性生效,重启后不会复原 : chkconfig iptables off

Mysql

日志文件导致磁盘空间过大

--    查看 日志文件
show binary logs  

--    删除日志文件
purge binary logs to 'LAPTOP-EMOMQ354-bin.000068';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000069';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000070';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000064';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000065';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000066';
purge binary logs to 'LAPTOP-EMOMQ354-bin.000067';

登录数据库
mysql -u root -h 127.0.0.1 -p
启动数据库
systemctl start mysqld.service
systemctl stop mysqld.service
systemctl restart mysqld.service

查看版本
status;
查看密码复杂度
show variables like ‘validate_password%’
修改密码
mysql> select user,host from user;

alter user ‘root’@‘localhost’ identified by ‘1234567’;
alter user ‘root’@‘%’ identified by ‘Gold9encis#’;

mysqladmin -u root -p password “goldencis”

修改密码复杂策略

set global validate_password.length=8;
set global validate_password.special_char_count=0;
set validate_password.policy = Low;

关于 mysql 密码策略相关参数; 1)、validate_password_length 固定密码的总长度;
2)、validate_password_dictionary_file 指定密码验证的文件路径;
3)、validate_password_mixed_case_count 整个密码中至少要包含大/小写字母的总个数;
4)、validate_password_number_count 整个密码中至少要包含阿拉伯数字的个数;
5)、validate_password_policy 指定密码的强度验证等级,默认为 MEDIUM; 关于
validate_password_policy 的取值: 0/LOW:只验证长度; 1/MEDIUM:验证长度、数字、大小写、特殊字符;
2/STRONG:验证长度、数字、大小写、特殊字符、字典文件;
6)、validate_password_special_char_count 整个密码中至少要包含特殊字符的个数;

配置失败处理策略

1.查看失败处理策略

show variables like '%connection_control%';

若返回
在这里插入图片描述
则 安装插件 命令如下:

install plugin connection_control soname "connection_control.so";

若返回
在这里插入图片描述
表示已安装过失败处理插件
2.修改配置文件
查看my.cnf所在位置

whereis my.cnf

进入所在位置,在mysqld所在区域追加如下配置

connection-control-failed-connections-threshold=3 #锁定此处
connection-control-min-connection-delay=10000 #锁定时间 10s

3.最后查看是否配置成功

show variables like '%connection_control%';

在这里插入图片描述

配置口令更换策略

# 使 expuser 账号密码立即过期
mysql> ALTER USER 'expuser'@'%' PASSWORD EXPIRE;
# 修改账号密码永不过期
mysql> ALTER USER 'expuser'@'%' PASSWORD EXPIRE NEVER;
#修改账号密码1天后过期
mysql> ALTER USER 'root'@'%' PASSWORD EXPIRE INTERVAL 1 DAY;

密码过期后会出现以下问题

You must reset your password using ALTER USER statement before executing this statement.

解决方法如下:

#密码重设
alter user 'root'@'%' identified by 'Gold9encis#';
#刷新
flush privileges;

开启日志审计

开启general_log
 
set global general_log=on
 
#检查验证
show variables like '%general_log%';
 
弊端:只要用户执行了操作,无论对错,MySQL就会记录日志,这样的话日志量会非常庞大,对数据库效率有影响

开启 SSL

set global require_secure_transport=ON;

maven

由于网络问题造成的批量包下载失败问题

清除下载失败的jar包

set REPOSITORY_PATH=你的maven仓库全路径
rem 正在搜索...
for /f "delims=" %%i in ('dir /b /s "%REPOSITORY_PATH%\*lastUpdated*"') do (
    del /s /q %%i
)
rem 搜索完毕
pause

将此段脚本写入bat文件中(mavenclean.bat),双击执行

内存模型

每个线程都只能访问自己的线程栈。
每个线程都不能访问(看不见)其他线程的局部变量。所有原生类型的局部变量都存储到线程栈中,因此对其他线程是不可见的
线程可以将一个原生变量值的副本传给另一个线程,但不能共享原生局部变量本身。
堆内存中包含了java代码中创建的所有对象,不管是哪个线程创建的。其中也涵盖了包装类型。
不管是创建一个对象并将其赋值给局部变量,还是赋值给另一个对象的成员变量,创建的对象都会被保存到堆内存中。

原生数据类型:
编程语言中的基本数据类型,也称为基本类型或内置类型。这些数据类型通常由语言本身提供,而不是由程序员定义。原生数据类型包括整数(如int、long、short)、浮点数(如float、double)、字符(如char)、布尔值(如bool)等

  • 如果是原生数据类型的局部变量,那么它的内容就全部类型保留在线程栈中
  • 如果是对象引用,则栈中的局部变量的槽位中保存着对象的引用地址,而实际的对象内容保存在堆中。
  • 对象的成员变量与对象本身一起存储在堆上,不管成员变量的类型是原生数值还是对象引用。
  • 类的静态变量则和类定义一样都保存在堆中

总结 : 方法中的原生类型和对象引用地址在栈上存储;其他(对象、类定义、静态变量)在堆上

另外 ,堆内存又称为"共享堆",堆中的所有对象可以被所有线程访问,只要能拿到该对象的引用地址
如果两个线程同时访问某个对象的一个方法,则他们都可以访问到这个对象的成员变量,但每个线程的局部变量副本式独立的,因此这也就导致了并发相关的问题

public class Example {
    private int count = 0;

    public void increment() {
        int localCount = count;
        localCount++;
        count = localCount;
        System.out.println("Thread " + Thread.currentThread().getId() + " : Count is " + count);
    }
}
 public static void main(String[] args) {
        Example ex = new Example();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                ex.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                ex.increment();
            }
        });

        t1.start();
        t2.start();
    }
结果
Thread 11 : Count is 2
Thread 11 : Count is 3
Thread 11 : Count is 4
Thread 11 : Count is 5
Thread 11 : Count is 6
Thread 12 : Count is 2
Thread 12 : Count is 7
Thread 12 : Count is 8
Thread 12 : Count is 9
Thread 12 : Count is 10

JVM内存整体结构

在这里插入图片描述

栈结构

在这里插入图片描述
每启动一个线程,JVM就会在栈空间栈分配对应的线程栈,如果使用了JNI方法,就会分配一个单独的本地方法栈(Navicat Statck)。某个线程在执行的过程中,一般会包含多个方法,比如A调用B、B调用C、C调用…每执行到一个方法,就会创建对应的栈帧。

程序计数器

  • 字节码通过读取程序计数器的值依次读取指令,从而完成顺序执行,循环,选择,异常处理等;
  • 另外在多线程的情况下,记录当前线程运行的位置;

堆结构

在这里插入图片描述
对是所有线程共用的内存空间 ,JVM将Heap 内存空间氛围年轻代和老年代两部分。

  • 年轻代 :新生区 存活区(s0 和 s1 ,s0和s1其中一个为0)
  • 老年代 :老年区(确定为长期存活的对象)

非堆

非堆不归GC管理,也分为三个区
元数据区、class space、 codeCache
元数据区 元空间使用的是直接内存 主要说的是方法区 存储类定义信息 运行时常量等;方法区中又包含常量池

public class MyClass {
    public static final String MESSAGE = "Hello, world!";
    public static final int NUMBER = 42;
}

1.8之后,将字符串常量池移动到了堆中,因为在堆中可以进行GC处理。

String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");

System.out.println(s1 == s2);  // true
System.out.println(s1 == s3);  // false
System.out.println(s1.equals(s3));  // true

堆外内存

是指不在 Java 堆中分配的内存空间。在 Java 中,所有的对象都是在堆中分配的,堆外内存则是指除了堆以外的内存空间,如直接内存(Direct Memory)。不归GC管理

哪些对象会在堆外内存?
1.NIO Buffer:Java 中的 NIO(New I/O)库提供了一种基于缓冲区(Buffer)的 I/O 操作方式,NIO Buffer 可以使用直接内存,以提高 I/O 操作的性能。下吗如下:

import java.nio.ByteBuffer;
public class DirectBufferExample {
    public static void main(String[] args) {
        // 分配直接内存
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

        // 操作直接内存
        directBuffer.putInt(123);

        // 释放直接内存
        directBuffer.clear();
    }
}

2.JNI 对象:Java Native Interface(JNI)允许 Java 代码调用本地代码,本地代码也可以调用 Java 代码。JNI 对象是在本地代码中分配的,因此它们通常分配在直接内存中。一般使用native 修饰

  
public class JNIExample {
    static {
        System.loadLibrary("JNIExample");
    }

    // 声明本地方法
    private native int add(int a, int b);

    public static void main(String[] args) {
        // 创建 JNIExample 对象
        JNIExample example = new JNIExample();

        // 调用本地方法
        int result = example.add(1, 2);

        // 输出结果
        System.out.println("Result: " + result);
    }
}

3.大对象:Java 中的大对象(Large Object)通常指内存占用比较大的对象,如大数组、大字符串等。由于这些对象占用的内存较大,如果将它们分配到 Java 堆中,可能会导致堆空间的不足。因此,这些大对象通常会分配到直接内存中。

常见错误

java.lang.OutOfMemoryError

  1. GC Overhead Limit Exceeded : 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误
  2. Java heap space:假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。(和配置的最大堆内存有关,且受制于物理内存大小。最大堆内存可通过-Xmx参数配置,若没有特别配置,将会使用默认值

java.lang.StackOverflowError

  1. 若栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候

JVM 启动参数

1. 系统属性参数

配置运行的环境变量 这些配置只影响当前的jar的运行情况

可以配置哪些参数?

操作系统环境变量中的任何任何一个
在这里插入图片描述

可以通过什么方式配置?

1.直接在系统环境变量中配置
2.在启动脚本中配置 如下
在这里插入图片描述
3.在代码中配置 如下
在这里插入图片描述

如何获取配置好的参数?

在这里插入图片描述

2. 运行模式参数

一般使用 -service 方式启动 内存管理的效率高

3. 堆内存设置参数

  • -Xmx: 指定最大堆内存 只与堆内有关系 与非堆和栈无关系
  • -Xms: 指定初始内堆内存 ,当指定的初始内存不够时,开始扩容直至Xmx; 一定要保持-Xms和-Xmx一致,否则可能回到值内存抖动
  • -Xmn: 等价于 -XX:NewSize,表示的是年轻代整体大小

使用G1垃圾回收是否还要用设置此值?

  • -XX: MaxPermSize=size :这是 JDK1.7 之前使用的。Java8 默认允许的Meta空间无限大,此参数无效。
  • -XX: MaxMetaspaceSize=size: Java8 默认不限制 Meta 空间,一般不允许设置该选项
  • -XX: MaxDirectMemorySize=size, 设置堆外内存 这个参数和 -Dsun.nio.MaxDireMemorySize效果相同
  • -Xss:设置每个线程栈的字节数,影响栈的深度。例如 -Xss1m 指定线程栈为1MB,与 -XX:ThreadstatckSize=1m 等价

4. GC 设置参数

  • -XX: +UseG1GC: 使用 G1 垃圾回收器
  • -XX: +UseConcMarkSweepGC: 使用 CMS 垃圾回收器
  • -XX: +UseSerialGC: 使用串行垃圾回收器
  • -XX: +UseParallelGC: 使用并行垃圾回收器

5. 分析诊断参数

-XX: ±HeapDumpOnOutOfMemoryError 选项,当 OutOfMemoryError 产生,即内存溢出(堆内存或持久代)时,自动 Dump 堆内存。 与 HeapDumpOnOutOfMemoryError 搭配使用,指定内存溢出时 Dump 文件的目录。
示例用法:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/heapdump.hprof

发生致命错误时 (fatal error) 执行的脚本例如,写一个脚本来记录出错时间,执行一些命令,或者 curl 一下某个在线报警的 url。示例用法: java -XX:OnError="gdb - %p"MyApp可以发现有一个 %p 的格式化字符串,表示进程 PID.XX: OnOutOfMemorvError 选项,抛出 OutOfMemorvError 错误时执行的脚本XX: ErrorFile=filename 选项,致命错误的日志文件名,绝对路径或者相对路径
-Xdebug -Xrunidwp:transport=dt socket,server=y,suspend=n,address=1506,远程调试

6. JavaAgent 参数

JDK内置命令行工具

jstat

在这里插入图片描述
在这里插入图片描述

jmap

  • jmap -heap pid
    打印堆内存的配置和使用信息
  • jmap -histo pid
    打印类占用空间
  • jmap -dump:format=b,file=xx.hprof pid
  • 生成快照

jstack

GC策略

标记清除法
先标记不可达对象 - >清除不可达对象 (导致内存碎片化)
标记复制法
标记存活对象->将存活对象复制到s1或者s0,清除eden区和其中一个存货区
标记清除整理算法
先标记不可达对象 - >清除不可达对象 (导致内存碎片化)-> 碎片整理 压缩

在进行标记的时候 程序停下来 标记并且清除完之后 程序再继续跑。对此是让全部停下来还是一部分停下来 有个不同的实现,也就有了不同的GC算法。

GC算法

串行GC

-XX:+UseSerialGC
对年轻代使用标记复制法 对老年代使用标记清除整理法
两者都是单线程,当进行GC 时,停止所有线程 ,只让一个CPU 进行垃圾回收,不能利用多核CPU

并行GC

-XX:+UseParallelGC
-XXParallelGCThreads= N 指定GC的核心线程数 不设置便是默认CPU核数
对年轻代使用标记复制法 对老年代使用标记清除整理法
在垃圾回收时,充分利用多CPU,同时进行垃圾回收

CMS GC

XX:+UseConcMarkSweepGC
其对年轻代采用并行 STW 方式的 mark-copy(标记-复制)算法,对老年代主要使用并发 mark-sweep(标记-清除)算法。

四种引用

强引用

new 一个对象便是强引用对象,如果一个对象具有强引用,在可达范围内,即使内存空间不够,即使报内存溢出错误 也不会回收该对象,

软引用

        SoftReference<String> ref = new SoftReference<>(str);
        str = null; // 释放强引用
        String value = ref.get(); // 获取软引用对象
        System.out.println(value); // 输出“hello”

当内存不足时,软引用对象会被回收,软引用同样也必须和引用队列一起使用。当垃圾回收器准备回收一个对象时,如果发现这个对象只存在软引用,而且内存不足,那么就会将这个软引用加入到引用队列中。开发人员可以通过检查引用队列中的软引用,来判断对象是否已经被回收。

弱引用

作用:用来解决内存泄漏的问题,比如ThreadLcoal
如果一个对象没有直接引用,仅存在弱引用,GC看到则会被回收掉

ThreadLocal

解决什么样的问题?

线程之间数据隔离,避免线程安全问题,帮助每个线程存储此ThreadLocal所代表的值

原理

ThreadLocal起作用最主要的东西依赖三方面的配置——Threadlocal,ThreadLcoalMap,Thread
每个Thread里有一个 ThreadLcoalMap,当为这个线程存储ThreadLocal所指定的对象时,先看看此Thread有没有ThreadLcoalMap,没有就创建;然后threadLocal 调用 set()方法,此threadLocal作为key,指向的对象作为value存入ThreadLcoalMap中;

ThreadLocal 内存泄露问题是怎么导致的?

ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。这样一来,ThreadLocalMap 中就会出现 key 为 null 的 Entry。假如我们不做任何措施的话,value 永远无法被 GC 回收,这个时候就可能会产生内存泄露。ThreadLocalMap 实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。使用完 ThreadLocal方法后 最好手动调用remove()方法

数据丢失问题

首先,ThreadLocalMap中所软引用的对象为本身的ThreadLcoal对象,另外软引用对象只有在没有直接引用的情况下才能被GC回收;
举个例子:

    public static void main(String[] args) {
        WeakReference weakReference = new WeakReference<>(new M());
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());
    }

输出结果:

threadlocal.M@1540e19d
null

第一次可以获取这个对象,在执行GC之后,此对象变获取不到了
换一种方式

    public static void main(String[] args) {
        M m = new M();
        WeakReference weakReference = new WeakReference<>(m);
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());
    }

输出结果:

threadlocal.M@1540e19d
threadlocal.M@1540e19d

第一次可以获取到对象,GC之后仍然能获取到对象,为什么?
根本原因是:弱引用的对象会在“没有直接引用之后被GC掉”不是"会被GC掉”(这种是软引用),ThreadLocal用弱引用是为了防止用完了不调用remove造成的内存泄漏,对正常使用没有影响,另外,用完之后还要手动的去清空此对象,因为GC只是回收的ThrealLcoalMap中ThrealLcoal这个key,而Map中的value没有回收

CAS

compare and swap

读取当前值E,进行运算得到A,先不更新,再次读取E,比较此时的E是否与上次读取的E相等,如果相等,将E更新为A
如果读取到E与上次不相等,再重复上面的步骤,读取,进行运算,比较,更新;
在这里插入图片描述

ABA 问题

什么是ABA问题
一个线程将A改为B,后B经过本线程或者其他线程又变成A,此时的A与上次的A不一样,这就是ABA问题
如何解决?
加版本号
比较时,不管比较值,还比较版本号

锁升级过程

在这里插入图片描述

前后端传参接收为null的问题

  1. @RequestBody:用来接收前端传递给后端的json字符串中的数据(数据在请求体中)
    前端 必须是 Content-Type:application/json
    在这里插入图片描述
    另外 raw 对应的是 Content-Type: text/plain

弄错后容易导致 后端接收到的参数为空

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值