JVM学习笔记

一、堆栈,垃圾回收相关

1、 -Xms:设置JVM堆的最小值,-Xmx设置堆的最大值。两者设置为一样则可避免堆自动扩展。-Xmn设置新生代大小

2、通过参数-XX:HeapDumpOnOutOfMemoryError可以让虚拟机在内存溢出时Dump内存堆转储快照

3、-Xss128k:设置栈容量

4、不停地创建线程会导致栈OutOfMemory异常,可以通过减少最大堆(-Xmx)和减少栈容量(-Xss)来换取更多的线程。

5、String.intern()是一个Native方法,用于将String对象包含的字符串添加到常量池(在方法区)中。

7、-XX:MaxDirectMemorySize限制本地直接内存大小。默认值为-Xmx大小。

8、引用的分类:强引用、软引用、弱引用、虚引用。4中引用强度依次减弱。

9、可以通过在finalize()方法中增加引用来拯救自己,但是finalize()方法只会被系统调用一次。

10、-XX:PretrnureSizeThreshold=字节数  参数设置大对象

该参数用于设置大小超过该参数的对象被认为是“大对象”,直接进入老年代。 

注意:该参数只对Serial和ParNew收集器有效。 

11、-XXMaxTenuringThreshold=数字  设置新生代的最大年龄

设置该参数后,只要超过该参数的新生代对象都会被转移到老年代中去。 

12、-XX:PrintGCDetails打印垃圾回收详细日志

13:、-XX:SurvivorRatio=8设置新生代中Eden区与一个Survivor区的空间比例是8:1

14、-verbose:gc 表示输出虚拟机中GC的详细情况.

15、HandlePromotionFailure设置是否允许空间分配担保失败(jdk6之后基本不用)

16、-XX:+HeapDumpOnOutOfMemoryError内存溢出时生成堆转储文件

17、-XX:MaxDirectMemorySize调整直接内存大小

18、-XX:+PrintGCApplicationStoppedTime打印系统停顿时间

二、JVM性能监控

1、jps虚拟机进程状况工具 

2、jmap -dump:format=b,file=xxx.bin 3500生成java堆转储快照,jhat xxx.bin加载文件并分析,使用7000端口可在浏览器查看分析结果。

三、Java 代码为何在虚拟机中运行,以及如何在虚拟机中运行。

之所以要在虚拟机中运行,是因为它提供了可移植性。一旦 Java 代码被编译为 Java 字节码,便可 以在不同平台上的 Java 虚拟机实现上运行。此外,虚拟机还提供了一个代码托管的环境,代替我们 处理部分冗长而且容易出错的事务,例如内存管理。 Java 虚拟机将运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本 地方法栈。Java 程序编译而成的 class 文件,需要先加载至方法区中,方能在 Java 虚拟机中运行。 为了提高运行效率,标准 JDK 中的 HotSpot 虚拟机采用的是一种混合执行的策略。 它会解释执行 Java 字节码,然后会将其中反复执行的热点代码,以方法为单位进行即时编译,翻译 成机器码后直接运行在底层硬件之上。 HotSpot 装载了多个不同的即时编译器,以便在编译时间和生成代码的执行效率之间做取舍。

1、从 Java 7 开始,HotSpot 默认采用分层编译的方式:热点方法首先会被 C1 编译,而后热点方法中 的热点会进一步被 C2 编译。

四、垃圾回收

1、CMS追求最短回收停顿时间,基于标记清除算法,特点是并发收集低停顿,CMS收集器运作过程:

(1)初始标记

(2)并发标记

(3)重新标记

(3)并发清除

2、G1收集器总体基于标记-整理算法,局部看是基于复制算法。G1运作过程:

(1)初始标记

(2)并发标记

(3)最终标记

(4)筛选回收

 

5分配堆中内存有两种方式:

  • 指针碰撞 如果JVM的垃圾收集器采用复制算法或标记-整理算法,那么堆中空闲内存是完整的区域,并且空闲内存和已使用内存之间由一个指针标记。那么当为一个对象分配内存时,只需移动指针即可。因此,这种在完整空闲区域上通过移动指针来分配内存的方式就叫做“指针碰撞”。
  • 空闲列表 如果JVM的垃圾收集器采用标记-清除算法,那么堆中空闲区域和已使用区域交错,因此需要用一张“空闲列表”来记录堆中哪些区域是空闲区域,从而在创建对象的时候根据这张“空闲列表”找到空闲区域,并分配内存。 综上所述:JVM究竟采用哪种内存分配方法,取决于它使用了何种垃圾收集器。

6初始化开始的时机:

  1. 在运行过程中遇到如下字节码指令时,如果类尚未初始化,那就要进行初始化:new、getstatic、putstatic、invokestatic。这四个指令对应的Java代码场景是:
  • 通过new创建对象;
  • 读取、设置一个类的静态成员变量(不包括final修饰的静态变量);
  • 调用一个类的静态成员函数。
  1. 使用java.lang.reflect进行反射调用的时候,如果类没有初始化,那就需要初始化;
  2. 当初始化一个类的时候,若其父类尚未初始化,那就先要让其父类初始化,然后再初始化本类;
  3. 当虚拟机启动时,虚拟机会首先初始化带有main方法的类,即主类;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值