ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JVM原理[总结笔记]

2020-07-14 21:01:35  阅读:211  来源: 互联网

标签:总结 虚拟机 笔记 线程 内存 JVM GC 方法


1.JVM内存模型

 

 

 

2.堆

  • 堆GC:

    • Minor GC 新生代垃圾回收动作,使用复制算法

    • Major GC/Full GC 老生代垃圾回收动作,使用标记清除算法,耗时较长,程序会stop the world

    • 老生代内存不足会发生Full GC,如果回收后还是不足,则抛出 java.lang.OutOfMemoryError: Java heap space

  • JVM管理的最大的一块内存区域,存放着对象的实例,是线程共享区。

  • JAVA堆的分类:

    • JVM内存划分为堆内存和非堆内存,堆内存分为年轻代(Young Generation)、老年代(Old Generation),默认比例为2:1,非堆内存就一个永久代(Permanent Generation)。

    • 年轻代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1

  • 堆内存用途:存放的是对象,垃圾收集器就是收集这些对象,然后根据GC算法回收。

  • 非堆内存用途:永久代,也称为方法区,存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。

  • 在JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是:元空间并不在JVM中,而是使用本地内存。元空间有注意有两个参数:

  • MetaspaceSize :初始化元空间大小,控制发生GC阈值

    • MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存

    • 新生成的对象首先放到年轻代Eden区,当Eden空间满了,触发Minor GC,存活下来的对象移动到Survivor0区,Survivor0区满后触发执行Minor GC,Survivor0区存活对象移动到Suvivor1区,这样保证了一段时间内总有一个survivor区为空。经过多次Minor GC仍然存活的对象移动到老年代。

    • 老年代存储长期存活的对象,占满时会触发Major GC=Full GC,GC期间会停止所有线程等待GC完成,所以对响应要求高的应用尽量减少发生Major GC,避免响应超时。Minor GC : 清理年轻代 Major GC : 清理老年代Full GC : 清理整个堆空间,包括年轻代和永久代,所有GC都会停止应用所有线程。

3.程序计数器

  • 程序计数器(Program Counter Register)是JVM中一块较小的内存区域,保存着当前线程执行的虚拟机字节码指令的内存地址(可以看作当前线程所执行的字节码的行号指示器)。

  • 如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址(可以理解为上图所示的行号),如果正在执行的是native方法,这个计数器的值为undefined。

  • JVM的多线程是通过线程轮流切换并分配CPU执行时间片的方式来实现的,任何一个时刻,一个CPU都只会执行一条线程中的指令。为了保证线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程间的程序计数器独立存储,互不影响。

  • 此区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域,因为程序计数器是由虚拟机内部维护的,不需要开发者进行操作。

4.虚拟机栈

  • 虚拟机栈(Java Virtual Machine Stacks)是线程隔离的,每创建一个线程时就会对应创建一个Java栈,即每个线程都有自己独立的虚拟机栈。这个栈中又会对应包含多个栈帧,每调用一个方法时就会往栈中创建并压入一个栈帧,栈帧存储局部变量表、操作栈、动态链接、方法出口等信息,每一个方法从调用到最终返回结果的过程,就对应一个栈帧从入栈到出栈的过程。

  • 虚拟机栈是一个后入先出的数据结构,线程运行过程中,只有处于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法,当前活动帧栈始终是虚拟机栈的栈顶元素。

  • 局部变量表存放了编译期可知的各种基本数据类型和对象引用类型。通常我们所说的“栈内存”指的就是局部变量表这一部分。

  • 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,运行期间不会改变局部变量表的大小。

  • 64位的long和double类型的数据会占用2个局部变量空间,其余的数据类型只占用1个

5.本地方法栈

  • 本地方法栈为Native 方法服务(虚拟机栈为java方法服务)。
  • 虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它

6.执行引擎

  • 负责解释执行java字节码指令

7.JVM 常用参数

-Xms堆内存初始大小,单位m、g
-Xmx(MaxHeapSize) 堆内存最大允许大小,一般不要大于物理内存的80%
-XX:PermSize 非堆内存初始大小,一般应用设置初始化200m,最大1024m就够了
-XX:MaxPermSize 非堆内存最大允许大小
-XX:NewSize(-Xns) 年轻代内存初始大小
-XX:MaxNewSize(-Xmn) 年轻代内存最大允许大小,也可以缩写
-XX:SurvivorRatio=8 年轻代中Eden区与Survivor区的容量比例值,默认为8,即8:1
-Xss 线程堆栈内存大小,最小128k,jdk1.5以后默认为1M

 

 

 

 

 

 

 

 

 

 

8.一个调参demo

设置虚拟机启动内存为512M,最大使用内存为1024M,每个线程大小512K

java -Xmx1024m -Xms512m -Xss512k -jar 3d-cloud-app-server-0.0.1-SNAPSHOT.jar --http.port=7000 --server.port=7001

 

标签:总结,虚拟机,笔记,线程,内存,JVM,GC,方法
来源: https://www.cnblogs.com/zincredible/p/13301605.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有