jvm学习笔记

java内存分为:
方法区,堆,本地方法栈,虚拟机栈,程序计数器


虚拟机栈中的局部变量表存储的都是基本类型还有对象的应用,局部变量表在编译结束后就确定大小了。


本地方法栈中的语言,使用方式和数据结构没有明确规定。其他和虚拟机栈并无二致


java堆,分代收集。


方法区,存储已被虚拟机加载的类信息,常量,静态变量。


运行时常量池是方法区一部分,Class文件中有一项信息是常量池存放各种字面量和符号的引用,这部分将在类加载后进入方法区运行时常量池中。


运行时方法区常量池中的数据并非完全来自于编译期Class的常量信息,也可以来自于运行期时放入其中。例如String类的intern()方法。


直接内存不是虚拟机运行时的数据区的一部分


为新对象分配内存在类加载完成就完全确定了,分配内存用的是指针碰撞还是空闲列表主要取决于内存规整,也就是垃圾收集器决定。


确保分配内存线程安全,有两种方式,一:通过CAS(compare and set)乐观锁来分配,二:每个线程在java堆中预先分配一小块内存,为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)只有TLAB用完并分配新的TLAB时,才需要同步锁定。
虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。


对象的对象头中存储了很多有用信息,那个类的实例,类的元数据寻找方式,对象的哈希码,对象的GC分代年龄。


对java虚拟机而言新的对象已经产生,java程序视角而言创建对象的过程才刚刚开始。(new 执行后再执行


对象的访问定位,java程序需要通过栈上的reference数据来操作堆中具体的对象,访问方式取决于具体的虚拟机而言(句柄访问,直接指针)。


句柄访问,堆中有一个句柄池,栈中存储了句柄的地址,句柄中存储了对象的实例数据和类型数据的具体地址信息


直接指针访问,reference中存储的是对象实例和到对象类型数据的指针,指向方法区中的对象类型数据


进程可分配到的内存是有限制的,32位的windows限制一个进程最大内存为2g,栈分配到的内存为2g-Xmx(最大堆内存)-MaxPermSize(最大方法区容量),


gc通过判断可达性来区分是否可以被回收


gc root分为 ,虚拟机栈中引用的对象,虚拟机栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI引用对象


jdk1.2后将引用区分为,强引用,软引用,弱引用,虚引用


对象在死亡之前会被标记两次,第一次可达性判断,第二次自行finalize()方法,对第一次标记对象进行筛选(就是看finalize方法有没有被重写或者已经被调用过了)


gc的可达性分析导致线程停顿


gc新生代一般采用复制收集的方式,老年代一版采用标记整理的方式。新生代gc快,老年代gc慢


java提倡的自动内存管理归结为自动化的解决了两个问题:给对象分配内存,回收分配给对象的内存。


分配内存优先分配到新生代Eden区,当Eden区域满时会执行一次Minor GC操作

你可能感兴趣的:(jvm学习)