对static有心得的高手进来讨论一下!

zhb_821012 2008-03-11 03:09:18
对static有体会的高手进来讨论一下它的优势和弊病吧!
我现在就先如果在一个程序中大量运用static定义的方法,那会不会使这个程序的稳定性受到影响呢?
我是这么理解的,定义为static后,在内存中单独给此方法开辟一块空间出来后,如果长时间运行这个有很多static方法的程序的话,这些内存不后被虚拟机垃圾收回,这样会不会就会影响程序的稳定性?
这是我的突然的一个想法,高手进来都说说吧!希望大家都能有所收获!
...全文
395 39 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
南南北北 2008-03-31
  • 打赏
  • 举报
回复
static方法,破坏了抽象、继承、多态。所以我们说它不够面向对象,至于是否面向对象,就仁者见仁了。

另外,一个方法所占用的内存是一定的,和它是不是静态的没有关系。

静态方法、变量,实例方法 一块内存区域(也许不是一块,但绝对不是堆上,不需要垃圾回收,占用空间只与方法大小有关,个人理解可能是代码段)。
实例变量+方法的引用 堆(垃圾回收的是这块)
调用方法 临时变量 栈(不需要垃圾回收)
sunyujia 2008-03-16
  • 打赏
  • 举报
回复
至于性能我觉得静态方法和普通方法是一样的,不过是静态字段占内存而已
sunyujia 2008-03-16
  • 打赏
  • 举报
回复
上面帖子太长不细看了,我的个人感觉是如果真的需要就用,很多时候导致参数过多用起来不爽,不够oo,那就用对象,至于内存占用,我觉得现在内存真的很便宜。
Z8157522 2008-03-15
  • 打赏
  • 举报
回复
精华帖,顶一个.学习了好多.
UnknowREN 2008-03-15
  • 打赏
  • 举报
回复
好的设计可以损失一定的性能,这样是值得的



期待高手继续
kekeemx 2008-03-14
  • 打赏
  • 举报
回复
其实我感觉很重要的一点是,一般STATIC方法都是作为工具类的某些通用方法存在的,
这样就很容易涉及到多线程调用的问题吧,所以我一般都是注意他在多线程环境下是否
会出现同步之类的问题,不知道这样对不对啊....来个高手啊.
sunwei_07 2008-03-14
  • 打赏
  • 举报
回复
学习了
zhb_821012 2008-03-14
  • 打赏
  • 举报
回复
好像静态的不会被回收器回收吧
这个还得再考察一下
一直没注意
zhb_821012 2008-03-13
  • 打赏
  • 举报
回复
晕有人理解错我意思了
不是说比一般方法多占内存
意思是不会被回收这个意思的多占
zapdos 2008-03-12
  • 打赏
  • 举报
回复
同意Gump09&楼上
睿音 2008-03-12
  • 打赏
  • 举报
回复
澄清一点:我是不赞同静态占内存多的。
[Quote=引用 14 楼 Gump09 的回复:]
类加载是不是把class文件加载进内存
[/Quote]
对于这点,我认为是确定的。在JVM加载Class的时候,是会在JVM内部实例化一个对应的Class(java.lang.Class)实例,对类中引用到的其他类加载并将类方法加载到JVM的Method Area中。

[Quote=引用 14 楼 Gump09 的回复:]
如果是那么实例方法和静态方法会不会都被加载
[/Quote]
对于这点,我想先纠正一下咱们现在的偏颇,我对lz的理解一直停留在static这个概念上,不知何时却转到了静态的方法上。类的方法在类被加载时是便已加载到虚拟机的Method Area中了。不论是否是静态方法。

[Quote=引用 14 楼 Gump09 的回复:]
如果是那么生成实例时静态方法会不会再生成一个。
[/Quote]
对于这点,我很赞同Gump09的这个词"引用",我感觉不论是静态方法还是非静态方法都是对JVM的Method Area的引用,不论是否是静态方法,应该都是不会再重复去加载到内存空间内。

[Quote=引用 14 楼 Gump09 的回复:]
如果不是那么类会不会被回收。
[/Quote]
对于这点,我的答案是确定的。类在加载时生成一个Class实例,对于这个实例JVM应该是可以去回收的,只是回收是在何时进行的。至少在JVM关闭前是一定会回收的。因为JVM不会将对Class占用内存的回收工作交给System去做。System应该只去回收JVM kernel所占用的内存。

[Quote=引用 14 楼 Gump09 的回复:]
如果还不是那么可以想象静态方法是和类同在的。至少它的数量比一个实例方法的数量不会多。
[/Quote]
方法是与类同在的。

先表述我的一个见解,由于方法和属性的加载是不同的。属性只有在实例化后得到Object的时候才会被分配内存,对于是否静态的区别也就在于是否持有多个副本,非静态属性(可能这个时候叫字段更合适)每个Object中持有一个副本,而静态字段所有的Object引用一个副本。

对于static我的感觉是给JVM的一个标示,标示是否允许JVM对这段占用的内存进行回收。这样我将这个话题也就转移到,JVM是何时对Class的实例进行回收。
joker_yao 2008-03-12
  • 打赏
  • 举报
回复
容易导致逻辑上的混乱
Gump09 2008-03-12
  • 打赏
  • 举报
回复
芯火兄 看的是哪本书啊 共享一下贝
睿音 2008-03-12
  • 打赏
  • 举报
回复
刚才细看了下,垃圾回收器仅是对堆空间进行管理。

这样说来我所说的“是给JVM的一个标示,标示是否允许JVM对这段占用的内存进行回收”是并不成立的了。而就像Gump09所

说仅是栈中引用的次数不同而已。
Gump09 2008-03-12
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 pizzame 的回复:]
说起这个我是很点背的,当时看inside JVM的时候是看的英文版,之后找到中文版了又懒得再看一遍~所以尤其是回收这里是有些蒙的。

我所知道的是类加载的实例是加载到Method Area的,而实例化后得到的对象是放入堆中的。JVM的动态回收机制是否会对Method Area回收否?
[/Quote]
这个我好像也见过。
对于加载有三步
1,得到类型的全限定名,产生字节流。
2,将二进制字节流加载到Method Area
3,创建一个java.lang.Class 实例来代表1产生的字节流
zhb_821012 2008-03-12
  • 打赏
  • 举报
回复
至于一般方法何时会被回收,那就不用考虑了,因为不是我们开发者能够控制的,这也是java当初努力实现的一个好处,这样避免了开发者将太多的精力放在对内存的分配使用上,从而极大的提高了程序开发的效率,这也是java的初衷,
zhb_821012 2008-03-12
  • 打赏
  • 举报
回复
恩不错,大家很多人都说到点在上了
其实关键的就是静态方法jvm不会去回收它了,因为他一开始从jvm的类装载器中装载的时候已经给这个方法做标记了
大家知道,jvm主要的一个组件就是类装载器,系统类装载器就不用考虑了,因为它不是我们开发者需要注意的,当一个用户类装载器把一个class二进制文件装载后,如果类中存在static方法,那么意味这对应开辟的内存不会被回收,一直到容易生命周期的结束,而一般方法开辟的内存是可复用的
所以说静态方法相对于一般方法是会多占用内存的
至于说的机器会吃不消这是肯定不可能的,还不至于
ee4456 2008-03-12
  • 打赏
  • 举报
回复
static 有其存在的特殊含义,可以实现普通函数和普通变量等,不能实现的功能,比如说单例模式,因为类在外部不能让他来new,那么你就写了个静态方法,用类名来直接调用返回一个他的实例
该用的时候用,
不该用的时候当然不用了,就和大家为什么都不把变量定义成全局变量一样的道理。
caven110 2008-03-12
  • 打赏
  • 举报
回复
内存肯定吃不消。程序一开始就把你的static属性和方法全都加载进来,你到时什么都不用做了
睿音 2008-03-12
  • 打赏
  • 举报
回复
说起这个我是很点背的,当时看inside JVM的时候是看的英文版,之后找到中文版了又懒得再看一遍~所以尤其是回收这里是有些蒙的。

我所知道的是类加载的实例是加载到Method Area的,而实例化后得到的对象是放入堆中的。JVM的动态回收机制是否会对Method Area回收否?
加载更多回复(16)

51,396

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧