3.JVM重要知识点

摘要:
1、 三个JVM II。堆(键)JVM只有一个堆内存,堆内存大小可以调整。1.新区域的目的是控制物体的诞生,生长和死亡分为:伊甸园:所有物体都来自伊甸园新区域,生存区域0和生存区域1:光GC后生存的物体。2.永久存在于老年区(养老区)的物品放置在老年区。步骤:伊甸园满后,进行轻GC。幸存对象被放置在生存区0或生存区1中。当伊甸园、生存区0和生存区1满时,进行重GC。幸存物品被放置在养老区???
一.三种JVM

3.JVM重要知识点第1张

二.堆(重点)
  • 一个JVM只有一个堆内存,堆内存大小是可以调节的

3.JVM重要知识点第2张

1.新生区

目的:控制对象的诞生,成长和死亡

分为:

  • 伊甸园区:所有对象都在伊甸园区new出来

  • 幸存0区和幸存1区:轻GC之后存下来的

2.老年区(养老区)

永久存在的对象放在老年区

步骤:

  • 伊甸园区满了之后进行轻GC幸存下来的放到幸存0区或幸存1区

  • 当伊甸园区、幸存0区和幸存1区都满了进行重GC,幸存下来的放到养老区???

  • 当伊甸园区、幸存0区、幸存1区和养老区都满了,会出现OOM

3.永久区

3.JVM重要知识点第3张

注意:

  • 元空间是逻辑上存在而物理上不存在的,又称为非堆,但是实际上是和堆放在同一个物理空间中

  • 方法区中的一小块为常量区

3.JVM重要知识点第4张

案例程序:

  • 默认情况下,JVM使用的最大内存为电脑总内存的四分之一,JVM使用的总内存为电脑总内存的十六分之一

  • 配置VM的参数: -Xms1024m -Xmx1024m -XX:+PrintGCDetails

@Test
public void test1() {
    //返回JVM试图使用的最大内存:默认情况下为电脑总内存的1/4
    long max = Runtime.getRuntime().maxMemory();
    //返回JVM的初始化总内存:默认情况下为电脑总内存的1/16
    long total = Runtime.getRuntime().totalMemory();

    System.out.println("max:" + max / (double) (1024 * 1024) + "MB");
    System.out.println("total:" + total / (double) (1024 * 1024) + "MB");

    //配置VM的参数: -Xms1024m -Xmx1024m -XX:+PrintGCDetails
}

3.JVM重要知识点第5张

 案例二:OOM

  • 配置VM的参数: -Xms8m -Xmx8m -XX:+PrintGCDetails

public class JVMTest {

    public static void main(String[] args) {
        //配置VM的参数: -Xms8m -Xmx8m -XX:+PrintGCDetails
        String s = "aaaaaaaaaa";
        while(true){
            s += s + new Random().nextInt(999999999) + new Random().nextInt(888888888);
        }
    }
}

3.JVM重要知识点第6张

 三.堆内存调优
  • 使用工具JProfiler

  • 内存快照分析工具:MAT(eclipse中使用),JProfiler

  • 作用:用于分析Dump文件,查找错误原因

使用步骤:

  • IDEA中在插件库中下载插件JProfiler

  • 在网上下载JProfiler桌面工具破解并安装

  • 在IDEA中配置JProfiler

3.JVM重要知识点第7张

 编写会OOM的代码,并配置VM options

3.JVM重要知识点第8张

编写程序

  • -Xms:设置初始化内存分配大小
  • -Xmx:设置最大分配内存
  • -XX:+PrintGCDetails:打印GC垃圾回收信息
  • -XX:+HeapDumpOnOutOfMemoryError:栈溢出信息生成Dump文件
//-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
public class Demo01 {

    byte[] array = new byte[1*1024*1024];   //1M
    public static void main(String[] args) {
        ArrayList<Demo01> list = new ArrayList<>();

        int count = 0;

        while(true){
            list.add(new Demo01());
            count++;
        }
    }
}

生成的dump文件在项目的目录下的xxx.hprof,双击打开

3.JVM重要知识点第9张

使用工具排错

3.JVM重要知识点第10张

3.JVM重要知识点第11张

 四.GC
  • Eden与Survivor的内存大小比例为8:1:1

3.JVM重要知识点第12张

3.JVM重要知识点第13张

1.引用计数法:

  • GC的时候会将计数器为0的对象C给销毁。

3.JVM重要知识点第14张

2.复制算法

  • 幸存区from和幸存区to中谁是空的谁就是to,我们会将to中数据复制到from中保持to中数据为空

  • from和to区实际上为逻辑上的概念,保证to区一直空

  • 默认对象经过15次GC后还没有被销毁就会进入养老区

3.JVM重要知识点第15张

流程:

  • 将Eden区进行GC存活对象放入空的To区,将From区存活的放到空的To区

  • 此时From区为空变成了To区,To区有数据变为From区

  • 经过15次GC后From区还存活的对象会被移动到养老区

3.JVM重要知识点第16张

好处:没有内存碎片

坏处:浪费了内存空间(To区为空)

复制算法最佳使用场景:对象存活度较低(如果存活度较高,则From区空间全部被占满导致会将全部内容复制到To区)

3.标记清除算法

  • 需要两次扫描,第一次扫描标记存活对象,第二次扫描清除没有被标记的对象

3.JVM重要知识点第17张

优点:不需要额外的空间

缺点:两次扫描严重浪费时间,并且还会产生内存碎片

4.标记压缩算法

  • 在标记清除算法上进行优化,再扫描一次将存活对象移动到一起

3.JVM重要知识点第18张

总结:

3.JVM重要知识点第19张

五.JMM
  • Java Memory Model:java内存模型

3.JVM重要知识点第20张

3.JVM重要知识点第21张

免责声明:文章转载自《3.JVM重要知识点》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇安卓开发之mqtt协议当shiro不进入自定义realm的权限认证方法时下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Redis性能篇(三)Redis关键系统配置:如何应对Redis变慢

Redis被广泛使用的一个很重要的原因是它的高性能。因此我们必要要重视所有可能影响Redis性能的因素、机制以及应对方案。影响Redis性能的五大方面的潜在因素,分别是: Redis内部的阻塞式操作 CPU核和NUMA架构的影响 Redis关键系统配置 Redis内存碎片 Redis缓冲区 在前面的2讲中,学习了会导致Redis变慢的潜在阻塞点以及相应...

mysql参数配置文件

(1)参数配置文件中的内容以键值对形式存在。 (2)如何查看键值对?show variables like '%name%';或者查看information_schema库下的global_variables视图; 如何修改呢? 1、innodb_buffer_pool_size=5G  2、客户端连接数据库的最大连接数:。通常,mysql的最大连...

my.cnf配置文件实用优化

[client] 1.登陆过程自动化(这样做可以让你在命令行登陆的时候免去输入用户名和密码) host="mysql服务器地址" user="用户名" password=“密码” 2.自动切换数据库(这样做可以避免每次进入都要use 某数据库) database="你的数据库名字" [mysqld] auto-rehash 启用TAB键自动补齐 skip-...

C++ 常见崩溃问题分析

一、前言 从事自动化测试平台开发的编程实践中,遭遇了几个程序崩溃问题,解决它们颇费了不少心思,解决过程中的曲折和彻夜的辗转反侧却历历在目,一直寻思写点东西,为这段难忘的经历留点纪念,总结惨痛的教训带来的经验,以期通过自己的经历为他人和自己带来福祉:写出更高质量的程序; 由于 C 和 C++ 这两种语言血缘非常近,文本亦对 C 编程语言有借鉴作用; 二、C+...

Java 堆内存 新生代 (转)

Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括...

判断栈和堆的生长方向

如何判断栈的增长方向? 对于一个用惯了i386系列机器的人来说,这似乎是一个无聊的问题,因为栈就是从高地址向低地址增长。不过,显然这不是这个问题的目的,既然把这个问题拿出来,问的就不只是i386系列的机器,跨硬件平台是这个问题的首先要考虑到的因素。 在一个物质极大丰富的年代,除非无路可退,否则我们坚决不会使用汇编去解决问题,而对于这种有系统编程味道的问题,...