JVM笔记

JVM

为什么要学习Jvm,学习Jvm可以干什么?

jvm为程序分配内存

JVM、JRE、JDK关系

JDK包含Jre、jre包含Jvm

jdk除jre、jvm外,还包含编译文件和对jvm信息进行监控

jre用来运行的基础环境,jvm编译class为文件,适配各操作系统

JVM运行时数据层区分?在这里插入图片描述

方法区:用于存放类信息、常量、静态变量以及编译后的代码。

堆(唯一作用):用于存放对象实例。

程序计数器(线程计数器):用来记录线程当前执行的行号,程序计数器之间互不影响。

本地方法栈:为虚拟机执行方法提供服务(C、C++代码)

虚拟机栈:生命周期同线程,一个方法绑定一个栈帧,栈帧存放局部变量、操作数栈、动态链接、出口。

能手动回收垃圾?

不能,能建议jvm进行垃圾回收,但是不能控制jvm何时进行垃圾回收

堆被分为新生代和老年代?

新生代:老年代=1:2

Eden:From Survivor:ToSurvivor=8:1:1

JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。

Minor GC、Major GC、Full GC区别及触发条件?

  • Minor GC新生代GC,用来回收新生代

触发条件:Eden区域满了或者新的新生代所需空间大于Eden现有空间

  • Major GC老年代GC,用来回收老年代

存活的新生代占用空间>老年代剩余空间

老年代空间满了

晋升老年代的新生代对象所需空间的平均大小>老年代剩余空间

执行system.gc()

CMS GC异常

堆内存分配很大的对象

怎么判断对象存活?

  • 引用计数法
  • 可达性分析
  • 标记-清除法
  • 标记-整理法
  • 复制法
  • 分代算法
    • 新生代用复制
    • 老生代用标记-清除法和标记整理法

什么是垃圾收集器?

Serial:复制法(单线程)

ParNew:复制法(多线程)

Parallel Scavenge:复制法(可控制吞吐量)

CMS:标记清除算法

Serial Old:标记-整理法(单线程)

Parallel Old:标记-整理法(多线程)

G1(复制法和标记-整理法):优化后的标记-清除法,可以同时作用与老年代和新生代,适用大内存、多处理器机器

  • 搭配

在这里插入图片描述

JVM参数配置

#常用的设置
-Xms:初始堆大小,JVM 启动的时候,给定堆空间大小。 

-Xmx:最大堆大小,JVM 运行过程中,如果初始堆空间不足的时候,最大可以扩展到多少。 

-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 使用本地线程的优先级,默认启用	

等等等......

JVM的GC收集器设置

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

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

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

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

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

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

类加载器

启动类加载器(BootStrap)

加载Java_home/jre/lib/rt.jar下的的所有类

拓展类加载器(ExtClassLoader)

加载Java_home/bin/ext下的类库

系统类加载器(AppClassLoader)

父类加载器为ExtClassLoader

自定义加载器()

父类加载器为AppClassLoader

双亲委派机制

**原理:**双亲委派机制,其工作原理的是,如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都很懒,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己才想办法去完成。

**优势:**采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。其次是考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。

到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值