[Java基础]——JVM内存模型

简介: [Java基础]——JVM内存模型

程序计数器:

程序计数器会保存下一条指令的地址!!!

如果是64位操作系统,也就是有64根地址线,那么地址对应的大小就是8个字节

本地方法栈:

存储一些用C++语言编写的 native方法

虚拟机栈:

函数入栈形成栈帧,函数执行完出栈,销毁栈帧。

每个线程都有自己的方法栈。

栈中的数据不会被垃圾回收

灵魂四问❓

栈帧包括什么:

       局部变量表 - 保存this和变量的。注意局部变量是可以复用内存槽的,int占1个槽位 long占2个槽位

栈内存会被JVM回收嘛:

       不会,方法调用完出栈

栈内存分配的越大越好吗:

       不是,因为栈内存大了,线程数就少了,并发少了,只是你单线程能调用的方法多了一点,并不让你运行速度变快,反而会慢。

方法内的局部变量是线程安全的吗?

       是的,因为每一个线程的栈帧是私有的,不会共享那个变量,如果变量加了static那就要考虑线程安全问题了。还有就是变量在参数或者返回值也都面临线程安全问题。

方法区:

1.8及以前:逻辑上是堆的一部分,它是所有线程共享的一块内存区域,他存储了类的成员变量、构造方法、类的结构、运行时常量池等。

1.8以后:从堆改为元空间,用的是操作系统的内存,但是这个运行时常量池还是在堆中。

区分串池和常量池

常量池:存放Class类的信息

串池:也叫运行时常量池,程序运行时,会将程序中第一次用到的常量存放到串池中,串池中维护的是一个HashTable,key就是字符串的地址,值就是字符串的内容。

故:

我们new出来的对象是在堆上的,地址不同,所以

String s1 = "ab";

String s2 = new String("ab");

s1 != s2;

像"a" + "b“这种在编译时编译器就优化了,从串池中找有无”ab"。

下面的代码很重要

        String s = new String("a") + new String("b");
        System.out.println(s.hashCode());
        String s2 = s.intern(); // 有返回串池中的对象,没有将s的引用放进去
        System.out.println(s.hashCode());
        String x = "ab";
        System.out.println(x.hashCode());
        System.out.println(s2.hashCode());
intern()方法应用实例

场景还原:流传推特要存储用户名和用户地址,但是这需要30个G的内存空间,并且呢,这些用户许多地址都是重复的,那么使用了intern之后,内存直接从30G变成了几百MB。

intern原理

       将字符串放到Stringtable中,Stringtable是内存中维护的一个Hashtable,也就是那个运行时常量池,它是由数组+链表/红黑树构成的,不允许重复,存储时根据hashcode算出的地址值,存到相应的位置。

       intern方法:

               如果StringTable中存在该字符串,直接返回字该字符串的引用,如果不存在,将该字符串的引用放入到StringTable中。

堆:

new 出来的对象就是在堆中存储的

堆中的对象会被JVM垃圾回收器回收。

直接内存(操作系统中的):

       如果Java要使用操作系统中的内存,需要创建两处缓存,一处是系统缓存区,一处是Java缓存区,这样就影响性能,如果使用bytebuffer中的某些方法创建的缓存,可以直接被我们Java程序使用。有待补充~

相关文章
|
11天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
4天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
6天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
21 6
|
2天前
|
Java Linux Windows
JVM内存
首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制。
6 1
|
10天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
31 2
|
11天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
28 1
|
21天前
|
存储 算法 Java
聊聊jvm的内存结构, 以及各种结构的作用
【10月更文挑战第27天】JVM(Java虚拟机)的内存结构主要包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和运行时常量池。各部分协同工作,为Java程序提供高效稳定的内存管理和运行环境,确保程序的正常执行、数据存储和资源利用。
45 10
|
17天前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
25 1
|
20天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
20天前
|
监控 安全 Java
Java Z 垃圾收集器如何彻底改变内存管理
大家好,我是V哥。今天聊聊Java的ZGC(Z Garbage Collector)。ZGC是一个低延迟垃圾收集器,专为大内存应用场景设计。其核心优势包括:极低的暂停时间(通常低于10毫秒)、支持TB级内存、使用着色指针实现高效对象管理、并发压缩和去碎片化、不分代的内存管理。适用于实时数据分析、高性能服务器和在线交易系统等场景,能显著提升应用的性能和稳定性。如何启用?只需在JVM启动参数中加入`-XX:+UseZGC`即可。
144 0