Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java static变量保存在哪?

Java static变量保存在哪?

作者头像
全栈程序员站长
发布于 2022-09-13 05:11:19
发布于 2022-09-13 05:11:19
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

测试环境:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Microsoft Windows [版本 10.0.17134.165]
java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.io.IOException;

public class Main {
    private static String name = "lgh";
    private static int age = 26;

    public int fun() {
        try {
            System.out.println(name);
            System.out.println(age);
            return System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static void main(String[] args) {
        new Main().fun();
    }
}

编译&运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
D:\N3verL4nd\Desktop>javac Main.java

D:\N3verL4nd\Desktop>java -XX:+UseSerialGC -XX:-UseCompressedOops -Xms10m -Xmx10m Main
lgh
26

System.in.read() 的作用等同于断点。

使用 CLHSDB 连接:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 查看进程 id
D:\>jps
5792 Jps
7932 Main

D:\>java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB
hsdb> attach 7932
Attaching to process 7932, please wait...

运行 universe

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Heap Parameters:
Gen 0:   eden [0x0000000012600000,0x00000000127114d0,0x00000000128b0000) space capacity = 2818048, 39.7239507630814 used
  from [0x00000000128b0000,0x00000000128b0000,0x0000000012900000) space capacity = 327680, 0.0 used
  to   [0x0000000012900000,0x0000000012900000,0x0000000012950000) space capacity = 327680, 0.0 usedInvocations: 0

Gen 1:   old  [0x0000000012950000,0x0000000012950000,0x0000000013000000) space capacity = 7012352, 0.0 usedInvocations: 0

[eden] 0x00000000128b0000 – 0x0000000012600000 = 2B 0000(1260 0000) [from] 0x0000000012900000 – 0x00000000128b0000 = 5 0000(120 0000) [to] 0x0000000012950000 – 0x0000000012900000 = 5 0000(120 0000)

可以看到 eden:from:to 大致比例为8:1:1,可以看到新生代的[eden-from-to]内存是连续的。同时可以看新生代和老年代内存是连着的。大概和垃圾回收方式有关。

扫描我们的 Main 实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hsdb> scanoops 0x0000000012600000 0x00000000128b0000 Main
0x000000001270afd8 Main
hsdb> whatis 0x000000001270afd8
Address 0x000000001270afd8: In thread-local allocation buffer for thread "main" (1)  [0x0000000012703870,0x000000001270b6e8,0x00000000127114b8,{
  
  0x00000000127114d0})

hsdb> inspect 0x000000001270afd8
instance of Oop for Main @ 0x000000001270afd8 @ 0x000000001270afd8 (size = 16)
_mark: 1
_metadata._klass: InstanceKlass for Main
hsdb>

可见,Main 实例分配在了线程私有的 TLAB 中。 Main 类没有实例变量,所以他的大小是 16 字节,Mark Word + Klass 指针(64 位 JVM 关闭压缩指针的情况下)。

使用 inspect 命令没有显示出来 InstanceKlass 也就是类型指针的地址,据说是 HSDB 的bug。我们使用 mem 来获取更详细的信息。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hsdb> mem 0x000000001270afd8 2
0x000000001270afd8: 0x0000000000000001 // Mark Word
0x000000001270afe0: 0x0000000013400598 // 类型指针(与Mark Word 一起组成对象头)

由于 1 个十六进制位代表 4 个二进制位,所以以上 Mark Word 的最后一位 1 代表的二进制序列为0001。

也就是 Main 实例处在无锁状态。

查看该类型指针对应的数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hsdb> inspect 0x0000000013400598
Type is InstanceKlass (size of 440)
juint Klass::_super_check_offset: 48
Klass* Klass::_secondary_super_cache: Klass @ null
Array<Klass*>* Klass::_secondary_supers: Array<Klass*> @ 0x0000000013000f88
Klass* Klass::_primary_supers[0]: Klass @ 0x0000000013001c00
oop Klass::_java_mirror: Oop for java/lang/Class @ 0x0000000012709dc8 Oop for java/lang/Class @ 0x0000000012709dc8

或者使用 HSDB :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
D:\Java\Tools\jol>java -XX:-UseCompressedOops -jar jol-cli.jar internals java.lang.Class
# Running 64-bit HotSpot VM.
# Objects are 8 bytes aligned.
# Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

Failed to find matching constructor, falling back to class-only introspection.

java.lang.Class object internals:
 OFFSET  SIZE                                              TYPE DESCRIPTION                               VALUE
      0    16                                                   (object header)                           N/A
     16     8                     java.lang.reflect.Constructor Class.cachedConstructor                   N/A
     24     8                                   java.lang.Class Class.newInstanceCallerCache              N/A
     32     8                                  java.lang.String Class.name                                N/A
     40     8                                                   (alignment/padding gap)
     48     8                       java.lang.ref.SoftReference Class.reflectionData                      N/A
     56     8   sun.reflect.generics.repository.ClassRepository Class.genericInfo                         N/A
     64     8                                java.lang.Object[] Class.enumConstants                       N/A
     72     8                                     java.util.Map Class.enumConstantDirectory               N/A
     80     8                    java.lang.Class.AnnotationData Class.annotationData                      N/A
     88     8             sun.reflect.annotation.AnnotationType Class.annotationType                      N/A
     96     8                java.lang.ClassValue.ClassValueMap Class.classValueMap                       N/A
    104    40                                                   (alignment/padding gap)
    144     4                                               int Class.classRedefinedCount                 N/A
    148     4                                                   (loss due to the next object alignment)
Instance size: 152 bytes
Space losses: 48 bytes internal + 4 bytes external = 52 bytes total

使用 jol 获得 Class 对象的大小为 152,也就是 19 个字长。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hsdb> inspect 0x0000000012709dc8
instance of Oop for java/lang/Class @ 0x0000000012709dc8 @ 0x0000000012709dc8 (size = 176)
name: "lgh" @ 0x000000001270af80 Oop for java/lang/String @ 0x000000001270af80
age: 26
hsdb> mem 0x0000000012709dc8 22
0x0000000012709dc8: 0x0000002a139a5501 // 1
0x0000000012709dd0: 0x0000000013013ed0 // 2
0x0000000012709dd8: 0x0000000000000000 // 3
0x0000000012709de0: 0x0000000000000000 // 4
0x0000000012709de8: 0x0000000000000000 // 5
0x0000000012709df0: 0x00000000126e5348 // 6
0x0000000012709df8: 0x000000001270a4c8 // 7
0x0000000012709e00: 0x0000000000000000 // 8
0x0000000012709e08: 0x0000000000000000 // 9
0x0000000012709e10: 0x0000000000000000 // 10
0x0000000012709e18: 0x0000000000000000 // 11
0x0000000012709e20: 0x0000000000000000 // 12
0x0000000012709e28: 0x0000000000000000 // 13
0x0000000012709e30: 0x00000000127097d0 // 14
0x0000000012709e38: 0x0000000000000000 // 15
0x0000000012709e40: 0x0000000000000000 // 16
0x0000000012709e48: 0x0000000013400598 // 17 类型指针
0x0000000012709e50: 0x0000000000000000 // 18
0x0000000012709e58: 0x0000001600000000 // 19
0x0000000012709e60: 0x0000000000000001 // 20
0x0000000012709e68: 0x000000001270af80 // 21 "lgh" 的引用
0x0000000012709e70: 0x000000000000001a // 22 "26" 的 16 进制表示

可以看到 static 变量保存在 Class 实例的尾部。 Class 对象确实在堆中。 类型指针保存在 Class 实例 17 * 8 的位置上。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160544.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用HSDB查看类变量的内存布局(5)
如下的实例来自Hotspot 垃圾回收之oop_iterate(一) 源码解析,我做了一些微小的改动。
全栈程序员站长
2021/04/07
8560
深入解析Java对象和类在HotSpot VM内部的具体实现
本篇讨论Java对象和类在HotSpot VM内部的具体实现,探索虚拟机在底层是如何对这些Java语言的概念建模的。
愿天堂没有BUG
2022/10/31
7710
深入解析Java对象和类在HotSpot VM内部的具体实现
实战案例分享:根据 JVM crash 日志定位和分析问题
下面是一份crash report, 下面是截取了crash report的部分,用于分析:
王知无-import_bigdata
2020/11/06
2.6K0
实战案例分享:根据 JVM crash 日志定位和分析问题
从虚拟机角度看Java多态->(重写override)的实现原理
工具与环境: Windows 7 x64企业版 Cygwin x64 jdk1.8.0_162 openjdk-8u40-src-b25-10_feb_2015 Vs2010 professional
我是小三
2018/08/08
1.5K0
从虚拟机角度看Java多态->(重写override)的实现原理
Java中的ArrayList与System.arraycopy底层原理
也就是说增长到1000的数组如果没有事先指定大小,会发生13次Arrays.copyOf动作,拷贝代价多大?继续分析
mingjie
2022/05/12
5860
HotSpot类模型之InstanceKlass「建议收藏」
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说HotSpot类模型之InstanceKlass「建议收藏」,希望能够帮助大家进步!!!
Java架构师必看
2022/02/16
1.2K0
HotSpot类模型之InstanceKlass「建议收藏」
不可不知的7个JDK命令
武培轩(公众号:武培轩)的《不可不知的7个JDK命令》这篇文章,短小精悍,介绍的这7个JDK命令非常实用,值得借鉴。
bisal
2020/05/18
4240
不可不知的7个JDK命令
垃圾收集分析(1)-Java对象结构(上)
GC(Garbage Collection)是目前很多编程语言自带的特性,例如Java,Python;GC是一个很好的特性,能让使用这个语言编程的程序员不去关心内存回收,并且降低内存泄漏和内存溢出发生的概率。 我们以Java语言JVM为例,从其对象结构和JVM运行时内存结构出发,针对其GC算法思路和实现进行分析,同时类比其他GC算法。 首先,在Java 8中,Java对象在内存中结构包括: 1. 类型指针:一个指向类信息的指针,描述了对象的类型。 2. 标记字(Mark Word):一组标记,描述了对象的状态,包括对象散列码(如果有)、对象的形状(是否是数组)、锁状态、数组长度(如果标记显示这个对象是数组,描述了数组的长度) 3. 对齐性填充:所有对象都是8字节对齐的 -> 也就是说,所有对象的起始位置都是满足A(A%8==0),所以对于有的对象需要这个对齐性填充来满足这个规则。 4. 域变量区域:这个对象的域变量所占用的内存。Java域变量存在两类:原始类型(primitive type)和普通对象指针(ordinary object pointer)。
干货满满张哈希
2021/04/12
3330
垃圾收集分析(1)-Java对象结构(上)
全网最硬核 JVM 内存解析 - 5.压缩对象指针相关机制
现代机器大部分是 64 位的,JVM 也从 9 开始仅提供 64 位的虚拟机。在 JVM 中,一个对象指针,对应进程存储这个对象的虚拟内存的起始位置,也是 64 位大小:
干货满满张哈希
2023/05/01
5260
全网最硬核 JVM 内存解析 - 5.压缩对象指针相关机制
JVM - 剖析Java对象头Object Header之指针压缩
同一个对象, 不开启指针压缩 8字节 存入堆中和 开启指针压缩4字节存入堆中,哪个更好一些,显而易见。
小小工匠
2021/08/17
1.1K0
8.JVM内存分配机制超详细解析
之前研究过类的加载过程。具体详情可查看文章:https://www.cnblogs.com/ITPower/p/15356099.html
用户7798898
2021/10/15
1.5K0
Java 对象在内存
1. Mark word: 记录线程,锁等对象状态,64位机占用8字节;32位机占用4字节; 当前主机是64位占8字节
一个架构师
2022/06/20
2510
Java 对象在内存
JVM - 剖析Java对象头Object Header之对象大小
JVM - 写了这么多年代码,你知不道new对象背后的逻辑? 中大体介绍了Java中 new 对象背后的主要流程,其中对象头的部分,我们仅仅是点到为止,这里我们深入剖一下Object Header的奥秘 。
小小工匠
2021/08/17
1.6K0
JVM 系列(4)一看就懂的对象内存布局 审核中
Java 中一切皆对象,同时对象也是 Java 编程中接触最多的概念,深入理解 Java 对象能够更帮助我们深入地掌握 Java 技术栈。在这篇文章里,我们将从内存的视角,带你深入理解 Java 对象在虚拟机中的表现形式。
用户9995743
2022/09/26
4750
JVM 系列(4)一看就懂的对象内存布局 审核中
聊聊openjdk的jhsdb工具
jhsdb: A New Tool for JDK 9这篇文章中列出了jhsdb与jcmd的等价命令,如下图:
code4it
2019/03/27
4K0
聊聊openjdk的jhsdb工具
Java GC详解 - 1. 最全面的理解Java对象结构 - 对象指针 OOPs
GC(Garbage Collection) 是目前很多编程语言自带的特性,例如Java,Python;GC是一个很好的特性,能让使用这个语言编程的程序员不去关心内存回收,并且降低内存泄漏和内存溢出发生的概率。
干货满满张哈希
2021/04/12
9220
Java GC详解 - 1. 最全面的理解Java对象结构 - 对象指针 OOPs
boolean 与boolean数组内存布局-Java快速进阶教程
首先,我们将检查 JVM 以查看对象大小。然后,我们将了解这些尺寸背后的基本原理。
jack.yang
2025/04/05
440
QEMU 的一些基础知识及QOM(Qemu Object Model)的部分相关源码阅读
QEMU(quick emulator)是一款由Fabrice Bellard等人编写的免费开源的可执行硬件虚拟化的(hardware virtualization)开源托管虚拟机(VMM)。还可以为user-level的进程执行CPU仿真,进而允许了为一种架构编译的程序在另外一种架构上面运行。
用户1423082
2024/12/31
3160
QEMU 的一些基础知识及QOM(Qemu Object Model)的部分相关源码阅读
JVM性能调优监控工具专题一:JVM自带性能调优工具(jps,jstack,jmap,jhat,jstat,hprof)
JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,每一种工具都有其自身的特点,用户可以根据你需要检测的应用或者程序片段的状况,适当的选择相应的工具进行检测。接下来的两个专题分别会讲VisualVM的具体应用。
java干货
2021/02/19
6890
JVM性能调优监控工具专题一:JVM自带性能调优工具(jps,jstack,jmap,jhat,jstat,hprof)
HotSpot源码分析之类模型
HotSpot采用了OOP-Klass模型描述Java的类和对象。Klass模型采用Klass类及相关子类的对象来描述具体的Java类。一般HotSpot JVM 在加载Java的Class 文件时,会在方法区创建 Klass ,用来保存Java类的元数据,包括常量池、字段、方法等。
全栈程序员站长
2021/04/07
5770
相关推荐
使用HSDB查看类变量的内存布局(5)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档