JVM读书笔记
1 概念
java virtual machine为java虚拟机,运行使用jdk中编译器编译的java程序。
2 JVM内存模型:5个
程序计数器:线程私有。当前线程正在执行的行号指示器。
Java虚拟机栈:线程私有。即将运行的java方法创建的区域。内存不足:java.lang.StackOverFlowError
本地方法栈:线程私有。即将运行的本地方法创建的区域。
堆:线程共享,空间大,存放对象。内存不足:java.lang.OutOfMemoryError
方法区:线程共享。存放加载的,类、常量、静态变量、即时编译器编译后的代码。
线程私有:生命周期和所属线程一样。
线程共享:jvm启动时创建,停止时销毁时
3 类加载过程
延伸:
类显示加载
类隐示加载
4 老生代和新生代
4.1 堆内存=老生代+新生代+持久代
老生代:存放生命周期比较长的对象。gc经过多次垃圾回收没有被回收的对象或者大对象。
新生代:存放新生成的对象。
4.2 各个内存分配
持久代一般固定为64M,新生代一般占据堆内存1/3,老生代为(堆内存-新生代内存-持久代内存)
5 如何设置jvm堆内存
5.1 idea设置jvm堆内存
找到idea的bin目录
确定jdk版本,根据版本选择不同的配置文件。
修改配置:idea.exe.vmoptions、idea64.exe.vmoptions
5.2 linux设置jvm堆内存
linux设置jvm堆内存
在文件/etc/profile最后加上一行 #export JAVA_OPTIONS=-Xms512m-Xmx512m
-Xms 堆内存初始分配值,默认为物理内存的1/64
-Xmx 堆内存最大值,默认为物理内存的1/4
-Xmn 新生代内存最大值
6 jvm问题排查
jstack:用于打印指定的java进程ID或core file 或远程调试服务的java堆栈信息
jmap:生成dump文件,查询finalize执行队列,java堆和永久代的详细信息,如当前使用率,当前使用的收集器等。
参考文档:《深入Java虚拟机(原书第2版).pdf》
问题
1、JVM加载class文件的原理机制:
(1)加载:把类的.class文件中的数据读入内存,产生加载类对应的Class对象。类加载器包括:根加载器(BootStrap),扩展加载器(Extension),系统加载器(System),用户自定义加载器(java.lang.ClassLoader的子类)。类加载过程采用父亲委托机制PDM。
(2)连接:验证,准备(为静态变量分配内存并设置默认的初始值),解析(将符号引用替换为直接引用)
(3)初始化:如果这个类存在直接的父类且这个类没有被初始化,则初始化父类;如果类中存在初始化语句,依次执行初始化语句。
2、java对象创建过程:
(1)检查新建对象的指令的参数能够在常量池中定义到一个类的符号引用,然后加载这个类
(2)为对象分配内存,指针碰撞、空闲列表->本地线程缓冲分配。
(3)将除对象头外的对象内存空间初始化为0
(4)设置对象头
3、java对象结构:对象头、实例数据、对齐填充
对象头:(1)对象自身的运行时数据,哈希码,GC分代年龄,锁标识状态,线程持有的锁,偏向线程ID;(2)指针类型,指向对象的类元数据类型(表示对象代表哪个类)
实例数据:存储对象真正的有效信息(父类继承下来的和自己定义的)
对齐填充:JVM要求对象起始地址必须是8字节的整数倍(8字节填充)
4、类的生命周期
加载:查找并加载类的二进制数据,在堆中
连接:验证、准备、初始化
初始化:为类的静态变量赋予正确的初始值
使用:new对象在程序中使用
卸载:执行垃圾回收
5、对象被回收判断方法:引用计数、可达性分析
引用计数:引用计数为0时,可以回收,缺点循环引用无法识别。
可达性分析:从GC Roots开始向下搜索,当一个对象没有引用链时,则证明此对象不可用,为不可达对象,可以回收。
6、垃圾收集算法:标记清除、复制、标记压缩、分代收集
7、Minor GC与Full GC分别在什么时候发生?
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!