jvm1-基础

https://docs.oracle.com/javase/7/docs/

JDK java de
JRE java runtime environment
JVM java virtual machine

内存溢出模拟
java.lang.OutOfMemoryError: java heap space

List<Demo> list = new ArrayList<>();
while(true){
    list.add(new Demo());
}

运行时数据区

线程独占区

程序计数器

1)程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器
2)程序计数器处理线程独占区
3)如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined
4)此区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

java虚拟机栈

1)虚拟机栈描述的是java方法执行的动态内存模型
2)栈帧
每个方法执行,都会创建一个栈帧,伴随着方法从创建到执行完成。用于存储局部变量表,操作数栈,动态链接,方法出口等
3)局部变量表

  • 存放编译器可知的各种基本数据类型,引用类型,returnAddress类型
  • 局部变量表的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在帧分配多少内存时固定的,在方法运行期间是不会改变局部变量表的大小

4)大小

  • 当栈不够时抛出StackOverflowError
  • 当栈足够大时,这个时候影响程序的可能就不是栈的大小了,而会是内存的大小,有可能会抛出OutOfMemory错误

栈溢出模拟
java.lang.StackOverflowError

public class StackTest{
    private void test(){
        System.out.println("方法执行");
    }
    
    public static void main(String[] args){
        new StackTest().test();
    }
}
本地方法栈

虚拟机栈为虚拟机执行java方法服务
本地方法栈为虚拟机执行native方法服务
其它与java虚拟机栈类似

线程共享区

Java堆 最大的一块内存区域

存放对象实例
垃圾收集器管理的主要区域
新生代、老年代、Eden空间
OutOfMemeryError

方法区

1)存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据
类信息:

  • 类的版本
  • 字段
  • 方法
  • 接口

2)方法区和永久代
3)垃圾回收在方法区的行为
在方法区做垃圾回收效率会很低,根据存放的内容可推断
4)异常的定义
OutOfMemoryError

运行时常量池 属于方法区

String 的问题
intern() 方法

直接内存

nio中会使用到

对象创建

给对象分配内存

  • 指针碰撞 (规整的内存快)
  • 空闲列表

内存分配线程安全性问题

  • 线程同步(加锁)
  • 本地线程分配缓冲(TLAB),缓冲使用完了再用加锁的方式增加内存

初始化对象

执行构造方法

对象的结构

https://www.cnblogs.com/zhengbin/p/6490953.html

  • Header(对象头)
    • 自身运行时数据(Mark Work)
      • 哈希值(object提供了本地方法hashCode获得对象hash值)
      • GC分代年龄(为分代回收算法服务)
      • 锁状态标志
      • 线程持有的锁
      • 偏向线程id
      • 偏向时间戳
    • 类型指针
      指向对象元数据的指针
      java数组的话对象头还会存储数组长度
  • InstanceData(数据实例)
    相同宽度的字段会存放到一起,比如Longs/doubles shorts/chars
    所以在父类定义的变量 可能会出现在子类之前
  • Padding(对齐填充)
    对齐填充不是必然存在的,没有特别的含义,它仅起到占位符的作用。
    由于 HotSpot VM 的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍,也就是说对象的大小必须是 8 字节的整数倍。对象头部分是 8 字节的倍数,所以当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

对象访问定位

  • 使用句柄
    好处:栈中引用地址不需要更改,更改的只是句柄池中的地址
  • 直接指针
    好处:减少了一次寻址过程性能高
    两种方式使用哪种取决于虚拟机实现
    hotspot使用的是直接指针的方式
原文地址:https://www.cnblogs.com/zh-ch/p/14167355.html