Java JVM

一、学习JVM可以干什么:
  1. 防止内存泄漏(Memory leak),防止内存溢出(Out of Memory);
  2. 了解线程锁的工作原理,进而优化线程锁的使用 (Thread Lock)提高性能;
  3. 科学进行垃圾回收 (Garbage collection);
  4. 提高系统吞吐量 (throughput);
  5. 降低延迟(Delay),提高其性能(performance)
二、字节码底层执行过程:

在这里插入图片描述

  1. JVM使用内置的javac指令机制将java对象编译为.class文件;
  2. 再讲.class文件转化为0101的二进制文件交给操作系统执行;
二、在主流的 JVM(例如 HotSpot)中,将 class 文件翻译成机器码执行时提供了两种方式:
  • 传统方式(解释执行器方式): 解释执行(边编译边执行);
    优点: 占用内存资源少,省去编译的时间,迅速执行;
    缺点: 边编译边执行,影响程序性能;
  • 非传统方式(编译执行器JNT方式): 编译执行(将热点代码编译后存入缓存,下次执行从缓存取,提高性能,热点代码指循环或高频使用的方法);
    优点: 提高了程序执行的性能;
    缺点: 占用内存资源多,程序开始执行时编译耗时;
三、JVM的三大组成部分:
  1. 类加载系统 (ClassLoader System): 负责加载类到内存;
  2. 运行时数据区 (Runtime Data Area): 负责存储数据信息,包括:
    共享:方法区,堆内存区;
    私有:栈内存区,本地栈内存区,程序计数器;
  3. 执行引擎 (Execution Engine): 负责调用对象执行业务,包括:解释执行器,编译执行器(JNT)和GC;
四、JVM运行时内存结构:

在这里插入图片描述

1. Heap (堆内存):

堆内存概要:

  1. 虚拟机启动时创建,被所有线程共享, 用于存放所有 java 对象实例.;
  2. 可分为年轻代(伊甸园区eden,From和To三部分)和老年代(Tenured);
  3. 是垃圾收集器(GC)管理的主要区域 ;
  4. 堆中没有内存分配时将会抛出 OutOfMemoryError

对象内存分配说明:

  • 新创建的对象一般都分配在年轻代,当对象比较大时年轻代没有足够空间还可直接分配到老年代。有时候系统为了减少GC开销对于小对象且没有逃逸的对象还可以直接在栈上分配。

对象分配总结:

  1. 一般分配在堆内存的新生代区;
  2. 大对象新生代空间不足时,可直接分配到老年代区;
  3. 小对象且没有逃逸的对象可直接分配到栈内存(逃逸指对象被外界引用);
//逃逸
Object obj;
public void method(){
	obj = new Object();
}

//没有逃逸
public void method(){
	Object obj = new Object();
}
  • 堆内存大小参数配置:
  1. -Xms 设置堆的最小空间大小;
  2. -Xmx 设置堆的最大空间大小;
  3. -XX:NewSize 设置新生代最小空间大小;
  4. -XX:MaxNewSize 设置新生代最大空间大小;
  5. -XX:NewRatio 新生代和老年代的比值,值为4则表示新生代:比老年代1:4;
  6. -XX:SurivorRatio 表示 Survivor 和 eden 的比值,值为 8 表示两个;
  7. survivor:eden=2:8;
  8. -Xss:设置每个线程的堆栈大小.
2. Method Area (方法区,也称作非堆内存)

方法区概要:

  1. 非堆内存,逻辑上的定义,用于存储类的数据结构(类结构)信息;
  2. 不同 jdk,方法区的实现不同,JDK8 中的方法区对应的是 Metaspace,是一块本地内存.

方法区内存配置参数说明:

  1. -XX:PermSize 设置永久代最小空间大小(JDK8 已弃用)。
  2. -XX:MaxPermSize 设置永久代最大空间大小(JDK8 已弃用)。
  3. -XX:MetaspaceSize 设置元数据区最小空间。 (JDK8)
  4. -XX:MaxMetaspaceSize 设置元数据区最大空间。(JDK8)
3. Program Counter Register(程序计数器)
  1. 线程启动时创建,线程私有;
  2. 用于记录当前正在执行的虚拟机字节码指令地址;
  3. Java 虚拟机规范唯一一个没有内存溢出的区域.
4. Stack Area (虚拟机栈区)

虚拟机栈概要:

  1. 用于存储栈帧(Stack Frame)对象,保存方法的局部变量表、操作数栈、执行运行时常量池的引用和一些额外的附加信息;
  2. 一次方法调用都会创建一个新的栈帧,并压栈。当方法执行完毕之后,便会将栈帧出栈。
  3. 栈上分配: 对于小对象()一般几十个 bytes),在没有逃逸的情况下,可以直接分配在栈上(直接分配在栈上,可以自动回收,减轻 GC 压力),大对象或者逃逸对象无法栈上分配

说明: 方法在进行递归调用时容器出现栈内存溢出

虚拟机栈参数说明:

  1. -Xss128k: 设置每个线程的堆栈大小

JDK5.0 以后每个线程堆栈大小为 1M,以前每个线程堆栈大小为 256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000 左右。

5. Native Stack Area (本地方法栈)
  1. 为虚拟机使用到的 Native 方法(C/C++代码)提供服务;
  2. 用于存储本地方法执行时的一些变量信息,操作数信息,结果信息
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值