当前位置: 首页 > news >正文

JVM内存分配

一、JVM内存区的划分

运行一个程序后,JVM会把内存划分为几个大区:程序计数器、Java虚拟机栈、本地方法栈、堆、方法区,以及一些辅助内存区如:运行时常量池、直接内存。各区域特点与作用如下:

1、程序计数器(PC Register

每条线程有一个,保存当前执行的字节码行号。类似于 CPU 的指令计数器,用以保证线程切换后能回到原来的位置。

2、Java 虚拟机栈(JVM Stack

每个线程有一个栈,里面一层层的是“栈帧”(方法调用时创建)。栈帧里存放局部变量表、操作数栈、动态链接信息、方法出口等。方法结束后,栈帧自动销毁。

所以:方法调用 = 压栈,方法返回 = 出栈

3、本地方法栈(Native Method Stack

专门给本地方法服务。比如 JNI 调用时会用到。

4、堆(Heap

所有线程共享,几乎所有对象都在这里分配GC 的主要工作区域。

堆区内部又进一步分代为新生代(Young Generation)和老年代(Old Generation),关于新生代和老年代的知识曾在JVM的垃圾处理机制中详细介绍

5、方法区(Metaspace,JDK8+

存储类元数据:类结构、常量池、静态变量、方法字节码。

JDK7 以前用 永久代(PermGen),JDK8 改为直接用本地内存的 Metaspace,避免 PermGen 容量不足。

6、运行时常量池

属于方法区的一部分,用于存放字符串常量、final 常量、符号引用等。

7、直接内存(Direct Memory

不属于 JVM 管理,而是直接用操作系统内存,主要目的是减少堆到系统内核的复制,提高 IO 性能。

二、Java程序运行时JVM的动态过程

1、编译:将源代码编译成.class文件

2、类加载器:把 .class 加载到 方法区,解析符号引用。

3、运行时:

(1) 线程运行时从 PC 计数器 知道执行哪行。

(2) 方法调用会往 JVM栈 压栈。

(3) 遇到 new 就在 堆 上分配对象。

(4) 需要 JNI 就进 本地方法栈。

三、对象储存结构

在运行时,会将绝大多数new出来的对象存放到堆区中,方法区中只会存放类信息,但是不会存放对象的实例,而在栈区中,由于对象是一个引用数据类型,只会存放对象的对象引用(指针),而不会存放对象的实例。

在堆区中,对象又被分为了三个区:对象头,实例数据,对齐填充。

1、对象头:包含存放哈希码、GC信息、类状态等的Markword(通常8字节)和指向对象所属类的元数据(通常为4到8字节,取决于是否使用压缩指针),一般对象头需要12~16个字节。

2、实例数据:存放对象的字段

3、对齐填充:由于JVM 要求对象的大小必须为8字节的倍数,所以如果当前对象的大小不满足要求,就必须要补齐,这就是对齐填充

当被询问Object的内存大小时,要注意其询问的是Object本身还是对象的实例,如果Object本身,实际上就是指存在栈区的对象指针,如果问的是对象的实例,就要算堆区的相关数据的大小

四、JNI是什么

Java本地接口(JNIJava Native Interface),是Java调用本地语言(如C++、Python)的代码的桥梁。由于Java是运行在JVM虚拟机中的,如果想要调用本地的代码如C/C++库,系统API,就需要使用到JNI

但是使用JNI也有一系列的缺点,例如跨平台性差(因为不是编译成字节码在JVM跑的),安全性下降(如果JNI的代码崩溃,可能导致JVM跟着一起崩溃)等。

JNI相关的语法如下:

public class HelloJNI {public native void sayHello();  // 本地方法(没有实现)static {System.loadLibrary("hello"); // 加载本地库}
}

然后在C++或者别的语言中实现即可(这里使用C++示例):

#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {printf("Hello from C!\n");
}

其中,native函数只是提示这里需要调本地方法,JVM会去对应的库中调用所有的对应的本地方法

五、JNI的调用过程

System.loadLibrary("hello");会让JVM去操作系统中加载一个动态链接库,这个库不会被放到 JVM 的方法区里,而是由操作系统的动态链接器把它加载到进程的本地内存空间。JVM 只是记下这个库,并在调用 native 方法时跳到对应的地址。

JNI运行时的调用过程如下:

1、Java 代码调用一个 native 方法。

2、JVM 发现这个方法没有 Java 字节码实现,于是切换到本地方法栈。

3、JVM 通过之前绑定的动态库地址,跳到对应的C/C++实现执行。

4、本地代码执行完毕后,返回结果,再切回 Java 栈。

http://www.dtcms.com/a/411828.html

相关文章:

  • 兴化网站建设网站开发用什么语言比较好
  • 四川网站建设找珊瑚云公司装修通知告示怎么写
  • 从 inode 角度深入分析软硬链接的内核实现与设计
  • 游戏开发中的状态管理与定时器
  • 上海网站开发外包分类信息网站
  • Apifox+DeepSeek接口测试实战
  • 7、幽络源微服务项目实战:SpringSecurity用户权限查询与校验的配置和测试
  • 海丰县建设局官方网站南县网站制作
  • 重庆企业建站模板佛山全网营销推广
  • 基于C#的停车场管理系统实现
  • html怎么做网站wordpress还能用
  • 有域名和空间怎么做网站简单网站设计网站
  • 操作系统之初识Linux
  • Transformers Dataset 完全指南:从基础到高级应用
  • 建设工程教育网站重庆网站推广多少钱
  • 广饶网站建设chenqinghua wordpress
  • (ST 表、博弈)洛谷 P8818 CSP-S 2022 策略游戏 题解
  • 怎么在百度搜索到我的网站一个互联网公司可以做几个网站
  • LangChain核心组件最新文档及示例代码(2025年更新)
  • Linux多进程编程(下)
  • django 网站开发视频教程百度竞价是seo还是sem
  • 平谷网站建设服务阿里邮箱企业版登录入口
  • [光学原理与应用-472]:半导体芯片生产、测试的产业链中使用到哪些种类的激光器,技术原理,主要供应商。
  • JxBrowser 8.11.0 版本发布啦!
  • 达梦数据库---实时主备配置
  • 东莞电子网站建设哪儿有上线了做网站多少钱
  • 深度学习复现:CIFAR-10 数据集任务的实现
  • CTF之文件包含
  • 做的比较好看的国内网站陕西省建设网三类人员考试时间
  • 建设商业网站长春做网站建设的公司