快速认识JVM

JVM

什么是JVM

JVM是java Virtual Machines,java虚拟机。java语言最大的特点:一次编译,处处运行(Write Once,Run Anywhere)就是基于JVM来实现的。Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行(可以理解为一个接口,然后不同的操作系统是不同的实现类),这个操作实现了一次编译,处处运行。由于JVM是JRE的一部分,所以只需要安装JRE,我们的java程序就能在不同的操作系统上来运行。

JVM内存模型

在这里插入图片描述

栈内存,存放8大基本类型数据,对象的引用,方法被调用的时候也会入栈,方法执行完后会出栈。

存放每个具体的对象,内部分为新生代、幸存代(from,to)、老年代、永久代(jdk1.8后称为元空间)。

新生代,每个对象new出来的时候都在新生代,99%的对象被gc回收的时候也在新生代(因为没有一直使用)。

新生代的对象每次被gc调用后,存活下来的对象就会进入幸存区,幸存区分为from和to两个区域,并且会不断交替转化(谁空谁是to)的过程(gc之复制拷贝法)。

老年代,在经过一定次数的gc回收后仍然存活就进入老年代,可以通过JVM参数 “-XX:MaxTenuringThreshold”来设置,默认情况是15次。在老年代的对象,轻gc是作用不到的,必须要重gc才能回收老年代的对象。

在新生代中触发轻gc,对象进入幸存区并进行from和to的区域及对象交换,如果幸存区已满,则进入老年区。当老年代进行重gc的时候,会回收新生代,幸存区,老年代中所有可回收的对象,如果老年代也满的情况下,下一次gc如果仍然没有可回收的对象的话,则会触发OOM(OutOfMemoryError)

方法区

定义上是一个特殊的堆,内部有一个运行时常量池,并且JVM在加载类的时候,也会给每一个类生成一个对应的class模板,这个模板对象也在这个方法区中。简单来说,static,final修饰的会进入方法区,class模板也在方法区,方法区内部还有一个运行时常量池。

方法区定义是在永久代中,永久代在jdk1.8以后也被称为元空间,元空间用的不是JVM的内存,而是本地内存。

本地方法栈

本地方法栈是存放JAVA中本地方法的地方,JAVA中的本地方法就是被native修饰过的方法,他是JAVA无法作用的范围,类似一个接口,接口去调用其他方法。不同的是,这个方法是由其他语言编写的,JAVA最开始是基于C和C++写的,他们希望JAVA能够抛弃掉C和C++的缺点,所以一开始也被称为C++ --,这边调用的方法就是由C和C++来实现的。

程序计数器

又被称为PC寄存器,是存放程序需要执行的下一条指令的地址。每个线程有自己的PC寄存器。

什么是GC

GC全称garbage collection,意味垃圾回收器,用于收集清除已经不需要再使用的对象,释放内存空间。

GC算法

  • 引用计数法:对象初始化的时候给对象一个值来表示调用次数,每次调用就给该值+1,然后每次gc进行垃圾回收的时候,就根据每个对象的调用次数来判断是否回收该对象。

    缺点:初始化的时候要给每个对象就创建一个值来表示调用次数,不仅耗时,而且浪费空间

  • 复制拷贝法:将内存空间二等分, 每次只使用其中一块. 当执行GC时, 将A部分的所有活动对象集体移到B中, 就可以将A全部释放。(就是幸存区中的from区和to区的例子)

    缺点:在极端情况下,如果A区的空间全部塞满了,那么进行复制拷贝法的时候,就是将A的全部空间复制到B…

  • 标记清除法:在gc回收的时候,对所有需要存活的对象进行标记,标记完成后,对所有对象进行筛选,没有被标记的直接被gc回收,有被标记的则存活下来。

    缺点:相当于要遍历2次所有对象,并且标记清除法释放后的空间不是连续的

  • 标记压缩法:在标记清除法的基础上,让存活下来的对象进行重新分配地址,保证内存空间连续

    缺点:比标记清除法更耗时

算法对比

效率:复制算法>标记清除法>标记压缩法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。

内存整齐度:复制算法=标记压缩法>标记清除法。

内存利用率:标记压缩法=标记清除法>复制算法。

GC算法优化

分代回收法:新生代和幸存代用复制算法,老年代用标记清除法+标记压缩法(进行n次标记清除后,再进行1次标记压缩法)

GC调优参数配置

-XX:MetaspaceSize=256m (元空间初始空间大小)

-XX:MaxMetaspaceSize=512m (元空间 最大空间,默认是没有限制的。)

-Xms1024m (设置JVM初始为1024m)

-Xmx1024m (设置JVM最大内存1024m)

-Xmn512m (设置年轻代大小为512m)

-XX:+PrintGCDetails (输出GC的详细日志)

-XX:+PrintGCDateStamps (输出GC的时间戳)

-Xloggc:/mnt/yyspace/logs/gc/system_gc.log (GC输出路径)

-XX:+UseGCLogFileRotation (启用GC日志文件的自动转储)

-XX:NumberOfGCLogFiles=3 (设置滚动日志文件个数为)

-XX:GCLogFileSize=2048K (设置滚动日志文件大小为)

-XX:+PrintStringTableStatistics 在JVM进程退出时,打印出StringTable的统计信息到标准日志输出目录中

-XX:+HeapDumpOnOutOfMemoryError 可以让JVM在出现内存溢出时候Dump出当前的内存转储快照。

-XX:HeapDumpPath=/mnt/yyspace/logs/heap/sys/(保存快照的地址)

-Dcom.sun.management.jmxremote (以下参数为开启远程监控)

-Djava.rmi.server.hostname=10.1.1.186

-Dcom.sun.management.jmxremote.port=8999

-Dcom.sun.management.jmxremote.authenticate=false

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.local.only=false

OOM异常分析

-XX:+HeapDumpOnOutOfMemoryError 可以让JVM在出现内存溢出时候Dump出当前的内存转储快照。

使用配置使得出现OOM的时候能够dump出内存快照文件,然后使用JProfiler来分析就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值