# Java JVM Basic Knowledge [TOC] ## JVM基础知识大整合 概述: 原文: https://zhuanlan.zhihu.com/p/132605554 非常详细: 原文: https://pdai.tech/md/java/jvm/java-jvm-struct.html ![](https://i.imgur.com/YpGy8j5.png) ### Minor GC、Major GC、Full GC的区别 原文: https://cloud.tencent.com/developer/article/1850327 ![](https://i.imgur.com/EKL7osx.png) Minor GC -> 创建对象的时候,一般是存放在eden space中,当eden space满的时候,就会触发对eden space的垃圾回收(Minor GC) (频率高) Major GC -> 年轻的对象变老时(存在足够时间后),就会去老年区 old space,当有年轻的对象进入到老年区,而这时的老年区满了的时候,就会触发对**全区**的垃圾回收(Major GC) (频率低,速度慢,因为要先扫描标记,后清除。) 所以一般Major GC 与 Full GC等价。 但是后来也有更细分的,分区GC和Full GC,分区GC就是分别对各自分区进行GC,而Full GC就是对全局进行GC。 ### 什么是Native Method 原文:https://www.jianshu.com/p/22517a150fe5 ![](https://i.imgur.com/daCYO8B.png) ### 内存溢出和内存泄漏是什么意思? 内存泄露就是申请的内存空间没有被正确释放,导致内存被白白占用。 内存溢出就是申请的内存超过了可用内存,内存不够了。 两者关系:内存泄露可能会导致内存溢出。 用一个有味道的比喻,内存溢出就是排队去蹲坑,发现没坑位了,内存泄漏,就是有人占着茅坑不拉屎,占着茅坑不拉屎的多了可能会导致坑位不够用。 ### 内存泄漏可能由哪些原因导致呢? 原文: https://tobebetterjavaer.com/sidebar/sanfene/jvm.html#_11-%E8%83%BD%E6%89%8B%E5%86%99%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E7%9A%84%E4%BE%8B%E5%AD%90%E5%90%97 ![](https://i.imgur.com/FVJjin1.png) #### hash 值发生变化 对象 Hash 值改变,使用 HashMap、HashSet 等容器中时候,由于对象修改之后的 Hah 值和存储进容器时的 Hash 值不同,所以无法找到存入的对象,自然也无法单独删除了,这也会造成内存泄漏。说句题外话,这也是为什么 String 类型被设置成了不可变类型。 如果无法理解上面这段话,请看下文: 原文: https://blog.csdn.net/zmx729618/article/details/51766641 很多人认为打印出的结果是1,但测试结果是2。为什么呢?当一个对象被存储在Hashset中后,**如果修改参与计算hashcode有关的字段**,那么修改后的hashcode的值就与一开始存储进来的hashcode的值不同了,这样**contains无法通过hashcode找到该元素**,所以无法删除。这就告诉我们,当一个对象被存储在Hashset中后,不要修改与计算hashcode有关的字段。 ### volatile关键词 原文:https://ifeve.com/java-volatile%E5%85%B3%E9%94%AE%E5%AD%97/#:~:text=Java%E7%9A%84volatile%E5%85%B3%E9%94%AE%E5%AD%97%E5%B0%B1%E6%98%AF%E8%AE%BE%E8%AE%A1%E7%94%A8%E6%9D%A5%E8%A7%A3%E5%86%B3,%E4%B8%BB%E5%AD%98%E4%B8%AD%E8%AF%BB%E5%8F%96%E3%80%82&text=%E5%B0%86%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%E4%B8%BA,%E5%AF%B9%E5%85%B6%E4%BB%96%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%8F%AF%E8%A7%81%E3%80%82 ![](https://i.imgur.com/bS4YbEL.png) 为什么要保证可见性,因为JVM中,除了Heap是线程共享的,其他都是线程私有的,如果要实现某些线程沟通的功能,就需要让线程的状态被另一个线程知道。 ### Java的四种对象引用 原文: https://blog.csdn.net/l540675759/article/details/73733763 ### JVM调优 #### 一些command ![](https://i.imgur.com/Pt7tktF.png) #### JVM 的常见参数配置知道哪些 一些常见的参数配置: **堆配置:** * -Xms:初始堆大小 * -Xms:最大堆大小 * -XX:NewSize=n:设置年轻代大小 * -XX:NewRatio=n:设置年轻代和年老代的比值。如:为 3 表示年轻代和年老代比值为 1:3,年轻代占整个年轻代年老代和的 1/4 * -XX:SurvivorRatio=n:年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。如 3 表示 Eden: 3 Survivor:2,一个 Survivor 区占整个年轻代的 1/5 * -XX:MaxPermSize=n:设置持久代大小 **收集器设置:** * -XX:+UseSerialGC:设置串行收集器 * -XX:+UseParallelGC:设置并行收集器 * -XX:+UseParalledlOldGC:设置并行年老代收集器 * -XX:+UseConcMarkSweepGC:设置并发收集器 **并行收集器设置** * -XX:ParallelGCThreads=n:设置并行收集器收集时使用的 CPU 数。并行收集线程数 * -XX:MaxGCPauseMillis=n:设置并行收集最大的暂停时间(如果到这个时间了,垃圾回收器依然没有回收完,也会停止回收) * -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为:1/(1+n) * -XX:+CMSIncrementalMode:设置为增量模式。适用于单 CPU 情况 * -XX:ParallelGCThreads=n:设置并发收集器年轻代手机方式为并行收集时,使用的 CPU 数。并行收集线程数 **打印 GC 回收的过程日志信息** * -XX:+PrintGC * -XX:+PrintGCDetails * -XX:+PrintGCTimeStamps * -Xloggc:filename