>拥有5000个大型线路或几个500-1000个线路类(如果所有这些都是加载的话)是否更好?
>每次实例化Object时,唯一的额外内存使用情况是实例变量引用
>对于没有实例变量的5000行类,加载类时的成本比例是多少?类文件的大小是粗略的近似值?
> jar文件的大小是否表示类将占用的内存的常规或最大大小?
在cruftex的回答后编辑:
这是我对课堂分裂的理解:
>拆分成逻辑块可以很好地改善代码重用和
减少行数
>它也使它更容易理解和
维护代码
这是我对类加载的理解:
>首次使用Class加载到内存中(使用的内存大致是类文件的大小)
>如果使用JIT,JIT编译器会创建一些额外的机器友好二进制版本,它使用更多的内存
>如果使用Hotspot,则只使用机器友好版本优化一些常用类(以平衡内存和速度)
>加载一个类后,创建其他实例的开销可以忽略不计(大约50-100个字节?)(假设没有实例变量)
>一旦加载了类,类本身就不会被垃圾回收
这是大致如何运作?
解决方法
For every new Class added to a Java application,what is the cost in terms of memory?
通常没关系.一般来说,只有一小部分(比如说5%)的整体内存使用被代码以各种形式占用.因此,即使您确实将代码大小减少了一半,整体内存使用量也只会略有下降.
相比之下,过长的源文件会使代码库难以导航,而较大的范围使得更难以全面了解类的功能以及某个更改是否安全.因此,长源文件会使修改代码变得更加昂贵且容易出错.
- On first use Class is loaded into memory (Memory used is roughly the size of the class file)
正确.
- If JIT is used,some additional machine-friendly binary version is created by the JIT compiler which uses a little more memory
- If Hotspot is used only some of the frequently used classes are optimised with machine-friendly versions (to balance memory and speed)
Hotspot是一个JIT,所以你在这里重复一遍.但是,是的,JIT确实增加了代码大小(但提高了速度).
Once a class is loaded,creating additional instances has negligible overhead (about 50-100 bytes?) (assuming no instance variables)
这是特定于JVM的.在Oracle Hotspot JVM上,每个对象的内存开销大约为8个字节,如以下程序所示:
public class Test { public static void main(String[] args) { Object[] array = new Object[10_000_000]; Runtime rt = Runtime.getRuntime(); long usedBefore = rt.totalMemory() - rt.freeMemory(); for (int i = 0; i < array.length; i++ ) { array[i] = new Object(); } long usedAfter = rt.totalMemory() - rt.freeMemory(); System.out.println(usedBefore); System.out.println(usedAfter); System.out.println((double)(usedAfter - usedBefore) / array.length); } }
- Once a class is loaded the class itself is never garbage collected
虽然它不是Java语言规范的强制要求,但我使用的每个JVM都会在ClassLoader无法访问时释放一个类(授予后,引导类加载器将始终保持可访问状态,但自定义ClassLoader可能无法访问).