ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux内存分区与JVM内存结构

Linux内存分区与JVM内存结构

LINUX系统 每个进程虚拟内存的分区:

  • 堆区:malloc等申请的动态内存
  • 栈区:局部变量,入参,出参,等
  • 代码段:程序编译后的二进制指令
  • 数据段:静态变量、全局变量
  • 内存映射段:mmap sendFile 等内存映射
  • 内核空间:系统内核代码,内核数据,用户态不可见

JVM其实就是LINUX的一个进程。然后jvm又对内存进行了jvm自己的划分。但是jvm其实就是一个c++程序,运行也需要内存,这部分直接向操作系统申请的不归jvm管理的叫做本地内存

直接内存:用来做内存映射 mmap sendFile

jvm内存分为以下几个部分(JVM内存结构):

  • 堆区:存放new出来的对象,放在虚拟内存的堆区
  • 虚拟机栈: 每个线程有自己的虚拟机栈,线程每调用一个方法,会向其虚拟机栈 放入方法的栈帧,方法调用完成,弹出栈帧。用于保存和恢复现场,放在虚拟内存的栈区
  • 本地方法栈:调用其他native方法( C/C++ 等非 Java 语言编写的方法),例如,Object 类中的 hashCode()、wait()、notify() 等方法,它们都有 native 关键字修饰,其具体实现就在本地方法库中。native方法不受jvm控制,本地方法栈主要为了native方法的保存现场和恢复现场,放在虚拟内存的栈区
  • 方法区:存放类的元数据,静态变量的引用(静态变量对象本身在堆区)等信息,jdk8之前在堆区永久代,jdk8之后在元空间(虚拟内存的内存映射段),主要是因为jvm堆区空间固定配置死的,但是内存映射段归linux系统管理,更有弹性
  • 常量池:属于方法区的一部分
  • 程序计数器:记录当前线程执行指令的行号,存放于虚拟内存的寄存器或者栈区

标量替换:如果一个封装对象,不作为入参,出参,作用域只是在方法内部,优化器会直接使用标量替换优化,把 对象的属性拆出来当做基本类型,直接放在栈区,不会在堆区创建对象, 如果这个对象特别大,也不会标量替换的

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进