这个问题我一直也想知道,说几个我目前可以做到的几点。 用过runtime的freememory方式获取jvm可分配内存的大小。但是无法确定单个对象的大小。只能计算所有装载后的总和。而且这里面已经不包含了被gc掉的。用类似c/c++的方式来获取。这里通过计算char int string等所有类型的长度来计算总和的方式获取对象大小。 但是这里jvm在创建对象过程中又同样会多出一写开销。同时对相同的string会在常量池里面存在一个。其它对象指向同一个常量池。通过第三方工具来做,比如楼上的jprofile或者bea也有类似的工具。
用过runtime的freememory方式获取jvm可分配内存的大小。但是无法确定单个对象的大小。只能计算所有装载后的总和。而且这里面已经不包含了被gc掉的。用类似c/c++的方式来获取。这里通过计算char int string等所有类型的长度来计算总和的方式获取对象大小。
但是这里jvm在创建对象过程中又同样会多出一写开销。同时对相同的string会在常量池里面存在一个。其它对象指向同一个常量池。通过第三方工具来做,比如楼上的jprofile或者bea也有类似的工具。
用runtime的total 减free
发现内存占用都是1.7m左右,是不是跟类的数量有关,而不是大小?
高手来啊。
用runtime的total 减free
发现内存占用都是1.7m左右,是不是跟类的数量有关,而不是大小?
高手来啊。
================和数量有关,和大小也有管。我虽然不知道你是如何测试的,但是如果你没有考虑gc和常量池的问题,
那么你的测试就是无效的。
那么多个类加载是多少内存?
总体上:不一定.
原因:
Class对象本身就是jvm的一个object子类,只在需要的时候才会加载,如果新的Class对象需要空间,旧的Class对象就会被回收.
除非你这样加载:
Class[] cs = new Class[1000000];
然后一个一个Class往里填.如果不是这样,你不用担心你那么多类型加载的时候内存不够用.
会不会释放?会释放。
机器内存不会太小吧。不管怎样,先调高jvm的内存。
也就是jvm的栈空间,c heap, java heap, java stack.
在不行就牺牲速度,延时加载。
还不行就加几台破机器做集群。
一般来说不用担心类太多会造成服务器内存不够用的情况(首先你的服务器是一个标准服务器,不是一个缩水版服务器,并且服务器只运行java项目,没有其它更多的内存输出),因为至今为止java的内存都在可控制范围内,没有出现因为类过多而造成内存不够用的情况,如果出现肯定是程序设计上有问题,跟java本身机制没有关系,这是经过这么长时间检测过来的并且可靠的。
所有的类在内存中其实生命周期是和对象一样的,类其实也是对象,同样需要创建(类应该是加载),同样可以销毁,这点是毋庸置疑的。而且jvm虚拟机也有当内存不足时强制销毁内存中的类的机制和销毁对象一样。
再说了,加载class消耗的内存是很小的,因为class文件是经过JVM编译的字节码序列而已,真正把服务器拖垮的是new出来的实例个数。这个区别希望你先明确,服务器在跑的过程中,不断的有实例被new出来,每次new一个实例都必须要分配一定的内存,当实例真正可以回收的时候GC会释放它占用的内存如果你担心内存不够用,最应该考虑的是你的class实例是否能被多线程复用,如果可以做到多线程提供服务class只需要单例就够了,这也是Spring默认提供的模式,一般业务逻辑的Service类都应该尽量做到单例复用来节约内存。总结两点:
1、之所以用Spring管理会节约内存,就是单例默认模式的原因
2、之所以用JProfile可以检测内存泄露,就是因为它可以检测出当前有多少个实例正占用着内存