JVM内存结构,程序计数器、方法区、堆区、虚拟机栈、本地方法栈。线程私有的有程序计数器、虚拟机栈;线程共享的有堆、方法区。
- 哪些会出现内存溢出的部分?
- 程序计数器不会出现内存溢出;
- 出现OutOfMemoryError的情况。堆内存耗尽:对象越来越多,又一直在使用,不能被GC回收;方法区耗尽:加载的类越来越多,很多框架都会在运行时动态产生新的类;虚拟机栈累积:每个线程都会占用内存空间,线程个数越来越多,而又长时间运行不及时销毁。
- 出现StackOverflowError的情况。虚拟机栈内部方法调用次数过多。
- 方法区与永久代、元空间之间的关系?
- 方法区是JVM管饭中定义的一块内存区域,用来存储类元数据、方法字节码、即时编译器需要的信息等;
- 永久代是Hotspot虚拟机对JVM规范的实现(1.8之前);
- 元空间是Hotspot虚拟机对JVM规范的实现(1.8之后),使用本地内存作为这些信息的存储空间。
- 内存模型以及各分区存放的信息?
- 方法区:存放类元数据,常量池(static常量、变量)、编译后的字节码等数据;
- 堆区:初始化的对象、成员变量(非static变量)、所有对象的实例和数组都在堆上分配;
- 栈:由栈帧组成,调用一个方法就压入一帧,帧上面存储局部变量表、操作数栈、方法出口等信息,局部变量表存放的是8大基础类型加上一个引用类型;
- 本地方法栈:native方法服务;
- 程序计数器:记录当前线程所执行的行号。
- 什么是Java的内存模型,各个线程怎么看到对象的变量的?
- 所有的变量都存放在主内存中,每个线程都有自己的工作内存。工作内存保存了线程使用到的变量主内存副本,线程对变量的操作都必须在工作内存中进行,不同线程之间无法直接访问对方工作内存的变量,线程间变量值的传递需要依赖主内存。
- volatile有什么特点?
- volatile是JVM提供的轻量级的同步机制,volatile变量对所有线程可见,通过内存屏障禁止指令重排序。synchronized既能保证可见性又能保证原子性,而volatile只能只能保证可见性、无法保证原子性。