JVM笔记

  • 内存快照如何抓取,怎么分析dump文件

  • 类加载器的认识,rt-jar ext application

  • jvm的位置

    • 运行在OS之上,和其他软件并行。java的东西运行在JVM
  • 线程的话,java只能去利用底层的。private native void start0();

  • 沙箱安全机制

  • 字节码校验器:检验类

  • Native

  • PC寄存器

  • 方法区

  • 栈和堆

  • 三种jvm

  • 新生区和老年区和永久区

  • 堆内存调优

  • GC(Garbage Collection)

    • 常用算法
  • jmm

JVM运行时数据区

  • method area:类,常量,常量池,静态变量,

  • heap(CG堆): 新生代,老生代。多个线程共享,可能划出线程的私有分区。没有内存将抛出OOM

  • 私有:PC程序计数器。Java虚拟机栈。本地方法栈

  • 线程结束,栈内存就释放了,对于栈来说,不存在垃圾回收

  • 栈内(栈帧):8大基本类型,对象引用,实例的方法

三种jvm:sun的hotspot

//native:说明java要调用底层。进入native method stack(内存区域),调用本地方法接口JNI
//本地方法栈是专门为了调用C/C++

堆分为

  • -XX:MaxTenuringThreshold=10默认是15
  • 老年区:
  • 永久区(元空间):非堆。存放jdk自身的class对象,存储的是一些运行环境或类信息,这个区域不存在垃圾回收。关闭jvm才回收。溢出:jar包,tomcat部署,反射类

CG垃圾回收:主要是在eden和老年区。99%都是临时对象

long l = Runtime.getRuntime().maxMemory();
long l1 = Runtime.getRuntime().totalMemory();
  • 文件:idea64.exe.vmoptions也有信息。增大内存可以提高启动速度
  • edit configurations:vm options:-Xms1024m -Xmx1024m -XX:+PrintGCDetails
  • X表示参数,memory size(默认1/64) ,memory max(默认1/4)。

OOM分析

  • 安装插件jprofiler。下载软件jprofiler。配置jprofiler插件路径/jprofiler.exe

  • 对Test.java文件进行edit configuration……,JV options:-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError

  • 运行Test.java(故意OOM),dump下文件进行分析

GC算法

  • 重复算法:没有内存碎片,总有一个区是空的。适用:对象存活度低
  • 标记清除法:两次扫描,有内存碎片
  • 标记整理法:没有内存碎皮,多了移动成本
  • 应用计数器法:

没有最好的算法,只有最合适的算法:GC --> 分代收集算法

  • 新生区:重复算法
  • 老年区:标记清除+标记整理 混合实现

基本

  • Hello.java经javac编译成,字节码类文件Hello.class,相邻之间没有缝隙,可以被JVM快速的加载至内存,并且占用较少的内存空间(利于网络传输),一次编译,多次使用。每个类单独一个class文件

  • .class文件结构:

    • magic字段:cafebase,判断是否是class文件
    • version字段:00 00 00 34 版本
    • constant_pool
    • 很多,等等
  • 由于jvm运行在OS上,jvm屏蔽底层硬件,指令的,java可以实现跨平台。

  • JDK,JRE,JVM

  • 学习JVM用于调优

深入学习

运行时数据区

  • class文件→JVM类加载器→JVM运行时数据区(需要引擎)

  • JVM运行时数据区(Runtime data area)

    • 方法区(非堆):类的信息,常量,静态变量。OutOfMemoryError
    • 堆(Heap,GC堆):实例对象。OutOfMemoryError
      • 新生代:eden,幸存区(from,to,总有一个空的)。eden满Minor GC。8:1:1。
      • 老生代:Full GC。1:2
      • 永久代=方法区
      • 可能划分出多个线程私有的分配缓冲区
    • PC:一个线程独有,记录执行的位置
    • 虚拟机栈:单位是栈帧(局部变量,操作数栈,动态链接,出口)。局部变量:8大基本数据类型,对象引用地址。操作数栈:i=8*8,然后放入局部变量表。出口:return
    • 本地方法栈:native(实现的方法在java中看不到),调用JNI(调用本地库)。本地方法栈就是C和C++代码
  • 一个方法调用另一个方法,会创建新的栈帧。

  • 栈指向堆:存储地址,指向堆的成员变量

JVM内存结构

  • 直接内存:取决于真实的内存大小。分配慢,读写快
  • 堆内存:分配快,读写慢

GC机制

  • 在程序运行过程中,一些对象不用了(不可达,对于程序而言,它已经死了),需要垃圾回收

  • System.gc();重GC只是建议执行垃圾回收,但什么时候执行不可知

  • finalize方法:Object的方法(所有的类都继承了它),在GC之前调用finalize方法

  • GC算法:堆的分类此时就显得尤其重要,不同的类用不同GC算法

    • 重复算法:新生区。浪费空间,节约时间
    • 标记清除:还要扫描,有内存碎片。配合标记整理,用于老年区
    • 标记整理:再浪费点时间整理一下碎片。
    • 分代算法:就是上面三种
    • 可达性
    • 引用计数

垃圾收集器

  • 垃圾收集器是GC算法的具体实现
  • 新生代收集器:Serial,ParNew,Parallel Scavenage,
  • 老生代收集器:CMS,Serial old(MSC),Parallel Old,
  • 整堆收集器:G1,,,

JVM参数配置

  • 内存参数
#常用的设置
-Xms:初始堆1/64

-Xmx:最大堆1/4

-Xmn:设置年轻代大小。堆=年轻代+年老代+持久代 

-XX:NewSize=n 设置年轻代初始化大小大小 

-XX:MaxNewSize=n 设置年轻代最大值

-XX:NewRatio=n 设置年轻代和年老代的比值。如: -XX:NewRatio=3,表示年轻代与年老代比值为 1:3,年轻代占整个年轻代+年老代和的 1/4 

-XX:SurvivorRatio=n 年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。8表示两个Survivor :eden=2:8 ,即一个Survivor占年轻代的1/10,默认就为8

-Xss:设置每个线程的堆栈大小。JDK5后每个线程 Java 栈大小为 1M,以前每个线程堆栈大小为 256K。

-XX:ThreadStackSize=n 线程堆栈大小

-XX:PermSize=n 设置持久代初始值	

-XX:MaxPermSize=n 设置持久代大小
 
-XX:MaxTenuringThreshold=n 设置年轻带垃圾对象最大年龄。如果设置为 0 的话,则年轻代对象不经过 Survivor 区,直接进入年老代。

#下面是一些不常用的

-XX:LargePageSizeInBytes=n 设置堆内存的内存页大小

-XX:+UseFastAccessorMethods 优化原始类型的getter方法性能

-XX:+DisableExplicitGC 禁止在运行期显式地调用System.gc(),默认启用	

-XX:+AggressiveOpts 是否启用JVM开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等,jdk6纸之后默认启动

-XX:+UseBiasedLocking 是否启用偏向锁,JDK6默认启用	

-Xnoclassgc 是否禁用垃圾回收

-XX:+UseThreadPriorities 使用本地线程的优先级,默认启用	

  • GC收集器设置
-XX:+UseSerialGC:设置串行收集器,年轻带收集器 

 -XX:+UseParNewGC:设置年轻代为并行收集。可与 CMS 收集同时使用。JDK5.0 以上,JVM 会根据系统配置自行设置,所以无需再设置此值。

-XX:+UseParallelGC:设置并行收集器,目标是目标是达到可控制的吞吐量

-XX:+UseParallelOldGC:设置并行年老代收集器,JDK6.0 支持对年老代并行收集。 

-XX:+UseConcMarkSweepGC:设置年老代并发收集器

-XX:+UseG1GC:设置 G1 收集器,JDK1.9默认垃圾收集器

类加载器

  • 加载:将静态数据→方法区的运行时数据结构,并在堆中生成类,java类加载器(系统类加载器)由JVM提供

  • 链接:把二进制合并到jre中,就是java二进制代码合并到jvm的运行状态之中

    • 验证:符合规范,没有安全问题
    • 准备:将类,static弄进方法区
    • 解析:
  • 初始化:执行类构造器<clinit>方法的过程

  • 类加载器分类(4):

  • 双亲委派机制:app→ext(jre\lib\ext)→boot(最终执行)。如果boot里面没有,再去ext,再去app

JVM可视化工具

  • jdk1.8.0_05\bin\jvisualvm.exe监视
  • jdk1.8.0_05\bin\jConsole.exe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值