在加载类A时,假设A的字节代码引用了许多其他类。假设A类如下所示。
class A extends B implements C,D {
static E e;
F f;
A() {
G g = new G();
}
void print(H h) {
}
}JVM是否加载了A使用的所有类?或者,在初始化类之前,它不会为它们操心?
如果其中至少有一些是加载的,那么在A完成之后会加载它们吗?或者A's加载会暂停到所需的类加载?
对于这个问题,假设还没有加载其他类。甚至是超类B和接口C & D。
发布于 2019-04-03 10:15:01
要理解这一点,让我们了解一些基本的这一点。这将帮助任何新手理解JAVA中的延迟加载。
如果您熟悉Netscape的Web浏览器,并且使用了3.x和4.x两种版本,那么毫无疑问,您已经注意到了Java运行时加载方式的不同。如果您查看Netscape 3启动时的启动屏幕,您将注意到它加载了各种资源,包括Java。但是,当您启动Netscape 4.x时,它不会加载Java运行时--它一直等到您访问包含标记的Web页面。这两种方法说明了急切实例化(在需要的情况下加载它)和延迟实例化(在加载之前等待请求,因为它可能永远不需要)的技术。
这两种方法都有缺点:一方面,如果在会话期间没有使用资源,那么总是加载资源可能会浪费宝贵的内存;另一方面,如果没有加载资源,则在第一次需要资源时就会付出加载时间的代价。
将延迟实例化视为资源保存策略。
Java中的延迟实例化分为两类:
延迟类加载
Java运行时内置了类的延迟实例化。类仅在第一次引用时才加载到内存中。(它们也可以首先通过HTTP从Web服务器加载。)
MyUtils.classMethod(); //first call to a static class method
Vector v = new Vector(); //first call to operator new延迟类加载是Java运行时环境的一个重要特性,因为它可以在某些情况下减少内存使用。例如,如果程序的一部分从未在会话期间执行,则将永远不会加载仅在程序的该部分中引用的类。
延迟对象创建
惰性对象的创建与延迟类的加载紧密耦合。当您第一次在以前没有加载的类类型上使用新关键字时,Java运行时将为您加载它。创建延迟对象可以大大减少内存使用,而不是加载懒散类。
为了介绍延迟对象创建的概念,让我们看一个简单的代码示例,其中一个框架使用MessageBox来显示错误消息:
public class MyFrame extends Frame
{
private MessageBox mb_ = new MessageBox();
//private helper used by this class
private void showMessage(String message)
{
//set the message text
mb_.setMessage( message );
mb_.pack();
mb_.show();
}
}在上面的示例中,当创建MyFrame实例时,MessageBox实例mb_也会被创建。同样的规则也适用于递归。因此,在MessageBox类的构造函数中初始化或分配的任何实例变量也在堆之外分配,依此类推。如果不使用MyFrame实例在会话中显示错误消息,我们就不必要地浪费内存。
在这个非常简单的例子中,我们不会得到太多。但是,如果您考虑一个更复杂的类,它使用许多其他类,而这些类反过来递归地使用和实例化更多的对象,那么潜在的内存使用就更加明显了。
public final class MyFrame extends Frame
{
private MessageBox mb_ ; //null, implicit
//private helper used by this class
private void showMessage(String message)
{
if(mb_==null)//first call to this method
mb_=new MessageBox();
//set the message text
mb_.setMessage( message );
mb_.pack();
mb_.show();
}
}如果仔细查看showMessage(),您将看到我们首先确定实例变量mb_是否等于null。由于我们还没有在声明点初始化mb_,所以Java运行时已经为我们解决了这个问题。因此,我们可以安全地创建MessageBox实例。以后对showMessage()的所有调用都会发现mb_不等于null,因此跳过创建对象并使用现有实例。
结论:一旦与子entities.To失去联系,就会加载所有依赖对象,减少内存占用,我们应该在诸如虚拟代理、延迟初始化等设计模式上仔细寻找这些类型的对象。
https://stackoverflow.com/questions/55492005
复制相似问题