您的位置:首页 > 教育 > 培训 > 开发定制直销系统_用户体验设计流程_快速网站排名优化_百度搜索高级搜索技巧

开发定制直销系统_用户体验设计流程_快速网站排名优化_百度搜索高级搜索技巧

2025/3/22 18:20:44 来源:https://blog.csdn.net/m0_71385141/article/details/146414165  浏览:    关键词:开发定制直销系统_用户体验设计流程_快速网站排名优化_百度搜索高级搜索技巧
开发定制直销系统_用户体验设计流程_快速网站排名优化_百度搜索高级搜索技巧

什么是JVM?

定义:Java Virtual Machine-java程序运行环境(java二进制字节码运行环境)
好处:

  • 一次编写,到处运行。
  • 自动内存管理,垃圾回收功能
  • 数组下标越界检查
  • 多态

比较:JDK JRE JVM
JDK、JRE、JVM比较
JVM内存结构:方法区、堆、虚拟机栈、程序计数器、本地方法栈
1、程序计数器(寄存器):记住下一条jvm指令的执行地址。
特点:线程私有的,每个线程都有自己的程序计数器。不会存在内存溢出
2、虚拟机栈:线程运行时需要的内存空间。栈帧代表每个方法运行时需要的内存(参数、局部变量、返回地址)。每个线程只有一个活动栈帧,对应正在执行的那个方法。
虚拟机栈
垃圾回收是否涉及栈内存?不涉及,因为每次栈帧出栈会自动释放内存,无需垃圾回收。
栈内存分配越大越好吗?(-Xss size指定内存)栈内存划分越大,线程数越少。只是增大了方法递归调用,也就是栈帧的数量。一个线程占用一个栈。
方法内的局部变量是否线程安全?
安全的,因为每个栈帧都有自己的局部变量,属于线程内私有的。 如果方法内局部变量没有逃离方法的作用访问,就是线程安全的。如果局部变量引用了对象,并逃离方法的作用方法时,需要考虑线程安全。
栈内存溢出:

  • 栈帧过多导致栈内存溢出
  • 栈帧过大导致栈内存溢出
    线程运行诊断:
  • cpu占用过多
  • 程序运行很长时间没有结果
    3、本地方法栈(Native Method Stacks):调用本地方法接口去实现,如clone();hashCode();notify();notifyAll();wait()
    4、堆(Heap)(控制堆空间内存溢出-Xmx):通过new关键字创建对象都会使用堆内存。
  • 堆内存诊断工具:
    ①jps工具:查看当前系统中有哪些java进程
    ②jmap工具:查看堆内存占用情况

jmap -heap 进程id

③jconsole工具:图形界面,多功能检测工具,可以连续监测
特点:它是线程共享的,堆中对象都需要考虑线程安全的问题。有垃圾回收机制。
垃圾回收后,内存占用仍然很高。?:(jvisualvm)通过堆转储功能dump快照排查,看看是哪些对象一直占用内存
** 5、方法区**
方法区内存溢出:
1.8以前会导致永久代内存溢出(java.lang.OutOfMemoryError:PermGen space)-XX:MaxPermSize=8m
1.8以后会导致元空间内存溢出(java.lang.OutOfMemoryError:Metaspace)-XX:MaxMetaspaceSize=8m
场景:spring,MyBatis
运行时常量池:常量池就是一张表,虚拟机指令根据这张表找到要执行的类名,、方法名、参数类型、字面量等信息。运行时常量池当该类被加载时,他的常量池信息就会放入(内存)运行时常量池,并把里面的符号地址变为真实地址。
StringTable
false(s1+s2为创建的新的实例对象,在堆内存中,而"a"+“b"存储在常量池中)
true
true(s4为创建的新的实例对象,发现常量池中已经存在"ab”,所以返回常量池对象)
false
StringTable的特性:串池中存储的仅为常量字符串

  • 常量池中的字符串仅是符号,第一次用到时才变为对象。
  • 利用串池的机制,来避免重复创建对象。
  • 字符串拼接的原理是StringBuilder
  • 字符串常量拼接的原理是编译器优化
  • 可以使用intern方法,主动将串池中还没有的字符串对象放入串池(1.8将这个字符串对象尝试放入串池,如果串池已经存在这个字符串,则不会放,如果没有则放入串池,并且返回串池中的对象 )
    StringTable的位置
    StringTable调优:
  • 调整-XX:StringTableSize=桶个数
  • 考虑将字符串对象是否入池
    6、直接内存(操作系统的内存)
  • 常用于NIO操作时用于数据缓冲区
  • 分配回收成本较高,但读写性能高
  • 不受JVM内存回收管理
    分配和回收原理:使用了Unsafe对象完成直接内存的分配回收,并回收需要主动调用freeMemory方法。ByteBuffer的实现类内部,使用了Cleaner(虚引用)来监测ByteBuffer对象,一旦ByteBuffer对象被垃圾回收,那么就会由ReferenceHandler线程通过Cleaner的clean方法调用freeMemory来释放直接内存。
    传统方法
    directBuffer

垃圾回收

1、如何判断对象可以回收?
可达性分析算法:

  • Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
  • -扫描堆中的对象,看是否能够沿着 GC Root对象 为起点的引用链找到该对象,若找不到,表示可以回收
  • 哪些对象可以作为 GC Root ?
  • 四种引用:强引用、软引用、弱引用、虚引用、终结器引用
    在这里插入图片描述
    强引用:只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收
    软引用(SoftReference):仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次出发垃圾回收,回收软引用对象。可以配合引用队列来释放软引用自身
    弱引用(WeakReference)仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象,可以配合引用队列来释放弱引用自身。
    虚引用(PhantomReference)必须配合引用队列使用,主要配合 ByteBufer 使用,被引用对象回收时,会将虚引用入队,由Reference Handler 线程调用虚引用相关方法释放直接内存
    终结器引用(FinalReference)无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队(被引用对象暂时没有被回收),再由 Fimalizer 线程通过终结器引用找到被引用对象并调用它的 finalize 方法,第二次 GC 时才能回收被引用对象

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com