java 加载类占用内存的问题?

daybybyby 2008-09-13 09:50:35
项目中需要用到xmlbean,schame文件有200多个,生成的类大约有150m大,但是服务器上内存有限。所以领导让我确定类在加载到内存以后一般占用多大。

比如有10000个类都同时load到jvm,这些类在jvm中大约多大? 会不会释放?

有没有这方面的讨论?
...全文
514 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
lgf606 2008-09-18
  • 打赏
  • 举报
回复
我认为会的!
dongqdonglin 2008-09-18
  • 打赏
  • 举报
回复
学习了
Ant 2008-09-18
  • 打赏
  • 举报
回复
我就不明白了,一般的工程怎么会加载1万个如此之多的类,即使整个Spring框架的源代码,也没有那么多类阿!
再说了,加载class消耗的内存是很小的,因为class文件是经过JVM编译的字节码序列而已,真正把服务器拖垮的是new出来的实例个数。这个区别希望你先明确,服务器在跑的过程中,不断的有实例被new出来,每次new一个实例都必须要分配一定的内存,当实例真正可以回收的时候GC会释放它占用的内存

如果你担心内存不够用,最应该考虑的是你的class实例是否能被多线程复用,如果可以做到多线程提供服务class只需要单例就够了,这也是Spring默认提供的模式,一般业务逻辑的Service类都应该尽量做到单例复用来节约内存。

总结两点:
1、之所以用Spring管理会节约内存,就是单例默认模式的原因
2、之所以用JProfile可以检测内存泄露,就是因为它可以检测出当前有多少个实例正占用着内存
acrobatyuer 2008-09-18
  • 打赏
  • 举报
回复
顶过...
jianghuxiaoxiami 2008-09-18
  • 打赏
  • 举报
回复
mark by jianghuxiaoxiami
zhongwenly 2008-09-18
  • 打赏
  • 举报
回复
才疏学浅,顶一下吧
zou_wei_forever 2008-09-16
  • 打赏
  • 举报
回复
关注ing...
haoweishow01 2008-09-16
  • 打赏
  • 举报
回复
收藏
树成 2008-09-16
  • 打赏
  • 举报
回复
一般来说jvm是如何管理类的主要看jvm的实现,不同的jvm实现对类对象的处理是不同的(首先我们的要肯定,类加载到jvm中成为一个对象并占用内存的,当然其中还有字段对象,方法对象等等)。有的jvm是一次性加载所有的类,有的是用到某个类的时候再加载,有的却是监测那些类频繁使用就加载它们并常驻内存,不常用就是用到的时候加载,用完销毁。
一般来说不用担心类太多会造成服务器内存不够用的情况(首先你的服务器是一个标准服务器,不是一个缩水版服务器,并且服务器只运行java项目,没有其它更多的内存输出),因为至今为止java的内存都在可控制范围内,没有出现因为类过多而造成内存不够用的情况,如果出现肯定是程序设计上有问题,跟java本身机制没有关系,这是经过这么长时间检测过来的并且可靠的。
所有的类在内存中其实生命周期是和对象一样的,类其实也是对象,同样需要创建(类应该是加载),同样可以销毁,这点是毋庸置疑的。而且jvm虚拟机也有当内存不足时强制销毁内存中的类的机制和销毁对象一样。
mayuanfei 2008-09-16
  • 打赏
  • 举报
回复
JDK6.0的Bin中有个工具.叫jvisualvm.exe.可以看你运行中的类占用的内存情况.
YSocket 2008-09-16
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 axman 的回复:]
看热闹,终于有人的问题可以测试出那些伪高手了.等着看表演.
预留三天,没人答我再来.
[/Quote]
自以为是的**
Gump09 2008-09-16
  • 打赏
  • 举报
回复
不过通常的做法都是单态,外加启动加载类,实例化类。
所以如果程序结构良好,那么就要调整机器性能。
Gump09 2008-09-16
  • 打赏
  • 举报
回复
[Quote=引用楼主 daybybyby 的帖子:]
项目中需要用到xmlbean,schame文件有200多个,生成的类大约有150m大,但是服务器上内存有限。所以领导让我确定类在加载到内存以后一般占用多大。

比如有10000个类都同时load到jvm,这些类在jvm中大约多大? 会不会释放?

有没有这方面的讨论?
[/Quote]
一般占用多大就是平均值,用jprofiler等工具可以看到总值,做个除法就好了。
会不会释放?会释放。
机器内存不会太小吧。不管怎样,先调高jvm的内存。
也就是jvm的栈空间,c heap, java heap, java stack.
在不行就牺牲速度,延时加载。
还不行就加几台破机器做集群。
axman 2008-09-16
  • 打赏
  • 举报
回复
有一位朋友崔我上来说现两句.我现在没有时间说太多,只说一个大概,但基本能说清楚.

1000000类加载会占多少内存?当然如果一个类本身有100m(10000000个字段,当然这样的类你定义的时候手肯定要抽筋的.)它当然至少要100m内存.
那么多个类加载是多少内存?
总体上:不一定.
原因:
Class对象本身就是jvm的一个object子类,只在需要的时候才会加载,如果新的Class对象需要空间,旧的Class对象就会被回收.
除非你这样加载:
Class[] cs = new Class[1000000];
然后一个一个Class往里填.如果不是这样,你不用担心你那么多类型加载的时候内存不够用.
chinagavin 2008-09-15
  • 打赏
  • 举报
回复
我试着用2k和18k的class各取10000个,看他们在内存中所占的大小。
用runtime的total 减free
发现内存占用都是1.7m左右,是不是跟类的数量有关,而不是大小?
高手来啊。。。。
================

和数量有关,和大小也有管。我虽然不知道你是如何测试的,但是如果你没有考虑gc和常量池的问题,
那么你的测试就是无效的。
power_115 2008-09-14
  • 打赏
  • 举报
回复
学习
chinagavin 2008-09-14
  • 打赏
  • 举报
回复
希望axman可以给出一个清晰深入的答案。
chinagavin 2008-09-14
  • 打赏
  • 举报
回复
这个问题我一直也想知道,说几个我目前可以做到的几点。
用过runtime的freememory方式获取jvm可分配内存的大小。但是无法确定单个对象的大小。只能计算所有装载后的总和。而且这里面已经不包含了被gc掉的。

用类似c/c++的方式来获取。这里通过计算char int string等所有类型的长度来计算总和的方式获取对象大小。
但是这里jvm在创建对象过程中又同样会多出一写开销。同时对相同的string会在常量池里面存在一个。其它对象指向同一个常量池。

通过第三方工具来做,比如楼上的jprofile或者bea也有类似的工具。
宋玮-深圳 2008-09-14
  • 打赏
  • 举报
回复
个人感觉碰到瓶颈了,需要冷静的重新分析一下你所需要做的事情。

spring当中的bean管理很有借鉴价值。 核心类,单例类,延时加载,都是一些思路
mengweilil 2008-09-14
  • 打赏
  • 举报
回复
http://andyao.javaeye.com/blog/146124

当然,自己可以找个profile工具看看。
加载更多回复(12)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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