发布于2026-07-05 阅读(0)
扫一扫,手机访问
静态变量属于类,存于元空间,随类加载而生、程序结束而亡;实例变量属于对象,存于堆内存,随对象创建而初始化、被GC回收时释放。
静态变量和实例变量在 JVM 里压根儿不是一回事——它们的存储位置、生命周期、共享方式,全由归属主体说了算:一个归类管,一个归对象管。下面咱们就把这几点掰开揉碎聊透。
静态变量是在类加载的时候被分配到方法区的(JDK 8 以后叫元空间),那地方存的是类型元信息——类结构、常量池、静态字段等。它不占堆内存,也不受常规垃圾回收的管辖。实例变量则完全不同:它没有独立的内存分配,而是作为对象的一个组成部分,嵌在堆里每个对象的实例数据区。每次你用 new 创建一个对象,JVM 就在堆上划出一块连续区域,把所有实例变量按声明顺序“打包”进去。
OutOfMemoryError: PermGen space。OutOfMemoryError: Metaspace。静态变量的生命周期跟类强绑定:类第一次被主动使用(比如 new 实例、调用静态方法、访问静态字段)时触发类加载,这时候静态变量完成分配和初始化;只要类没被卸载(这种情况极少见),它就一直活着。
实例变量的生命周期则完全依附于对象:对象通过 new 创建的时候,实例变量才被初始化(顺序是父类字段 → 父类构造器 → 子类字段 → 子类构造器);对象失去所有强引用后,一旦被 GC 回收,它占的那块堆空间(包括所有实例变量)就立刻释放。
new 过任何实例,它的静态变量也已经存在并且可以访问。静态变量天然是共享的:所有实例共用同一份值,任何一个地方改了,其他地方立马就能看到。原因很简单——它只有一份内存拷贝,而且待在类级别的空间里。实例变量则天然是隔离的:每个对象都有自己独立的一份副本,修改 A 对象的 field 完全不影响 B 对象同名 field。这种独立性,正是面向对象封装和状态管理的基础。
类名.变量名 来访问,语义最清晰;用对象访问语法虽然允许,但容易造成误解。this 上下文),必须显式传入对象引用才行。静态变量如果长期持有大对象的引用(比如静态 Map 缓存了大量业务对象,或者静态字段保存了没关闭的数据库连接),会导致这些对象永远无法被 GC 回收——哪怕所有相关业务对象早就销毁了,这个“悬挂引用”仍然锁住堆内存,最终造成内存泄漏。实例变量则天然受对象生命周期约束,风险小得多:只要对象被回收,它持有的所有实例变量及引用都会一并释放。
WeakReference)或软引用(SoftReference)包装。static Map)务必配上合理的淘汰策略或定时清理机制。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8