《深入JAVA虚拟机》一书中介绍,每一个JAVA应用程序都创建一个虚拟机实例,并运行在这个实例里,通过给虚拟机实例配置xmx改变堆内存大小。我突然想到,能否让一个虚拟机实例里的运行的应用程序所调用的类运行在另一个虚拟机实例里?
这个很有现实意义,用处最大就在J2EE缓存,大家都知道应用服务器给JVM分配的堆内存不可能无限制涨大,例如到2G后就无法再大,可是服务器可能有8G内存,另外6G浪费了?(如果再跑其他应用恐CPU不够,跑单机集群就是利用另外6G内存再装3个应用服务器),我在想,2G已经很小了,能不能将缓存这样的“有了更好,没有也没事”的东西让其运行在另一个虚拟机实例里(占用另外6G内存空间),而不与2G的核心数据存储争抢空间。如果说之前调用缓存管理器  CacheManager.getInstance()这样的话,换成Runtime.exec("CacheManager.jar");......是不是相当于将其运行在另一个JVM中?

解决方案 »

  1.   

    是可以实现的,Java的远程方法调用(RMI)就是解决跨虚拟机而设计的,你可以看一下RMI相关的资料,因为这也是一时讲不清的。网上资料很多,相信很快你就会找到很多关于RMI的资料。
    比如很有争议的ejb2,他要有专门的ejb服务器,而web应用程序要有web服务器,这两个服务器可以布置在不同的机器上,当然每个机器上都要安装JDK,也就是每个机器上都要有一个java虚拟机,此时就要用到RMI——远程方法调用。ejb服务器如JBOSS,Web服务器如Tomcat。
      

  2.   

    Runtime另起一个,应该是相当于另起了一个进程。
    2G的上限……没听说过,偶很浅薄的说。
    但是,对应用程序而言,不都是有4G可寻址空间吗?为什么对VM就有限制了?
      

  3.   

    当然可以 RMI 就是这样的
      

  4.   

    用WEBService,EJB也能实现远程调用的
      

  5.   

    都说RMI是JAVA实现分布式体系的基础,听了大家的意见才知道,所谓的分布式并非指将运算分布在不同机器上,而是分布在不同的虚拟机里,当然一般情况下不同虚拟机是运行在不同机器上的,但是也可以在本机开启多个虚拟机,作单机分布式,我得理解对么?
      

  6.   

    我认为,多虚拟机不一定就是分布式的,你可以多看一下虚拟机方面的书,还有就是J2EE方面的资料,就能对两种概念有了较深的了解了,下面我摘了一些文档是关于虚拟机方面的,你看看对你有没有帮助:
    一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序。程序开始执行时他才运行,程序结束时他就停止。你在同一台机器上运行三个程序,就会有三个运行中的Java虚拟机。   Java虚拟机总是开始于一个main()方法,这个方法必须是公有、返回void、直接受一个字符串数组。在程序执行时,你必须给Java虚拟机指明这个包换main()方法的类名。   Main()方法是程序的起点,他被执行的线程初始化为程序的初始线程。程序中其他的线程都由他来启动。Java中的线程分为两种:守护线程 (daemon)和普通线程(non-daemon)。守护线程是Java虚拟机自己使用的线程,比如负责垃圾收集的线程就是一个守护线程。当然,你也可 以把自己的程序设置为守护线程。包含Main()方法的初始线程不是守护线程。   只要Java虚拟机中还有普通的线程在执行,Java虚拟机就不会停止。如果有足够的权限,你可以调用exit()方法终止程序。 
    在Java虚拟机的规范中定义了一系列的子系统、内存区域、数据类型和使用指南。这些组件构成了Java虚拟机的内部结构,他们不仅仅为Java虚拟机的实现提供了清晰的内部结构,更是严格规定了Java虚拟机实现的外部行为。   每一个Java虚拟机都由一个类加载器子系统(class loader subsystem),负责加载程序中的类型(类和接口),并赋予唯一的名字。每一个Java虚拟机都有一个执行引擎(execution engine)负责执行被加载类中包含的指令。   程序的执行需要一定的内存空间,如字节码、被加载类的其他额外信息、程序中的对象、方法的参数、返回值、本地变量、处理的中间变量等等。Java虚拟机将 这些信息统统保存在数据区(data areas)中。虽然每个Java虚拟机的实现中都包含数据区,但是Java虚拟机规范对数据区的规定却非常的抽象。许多结构上的细节部分都留给了 Java虚拟机实现者自己发挥。不同Java虚拟机实现上的内存结构千差万别。一部分实现可能占用很多内存,而其他以下可能只占用很少的内存;一些实现可 能会使用虚拟内存,而其他的则不使用。这种比较精炼的Java虚拟机内存规约,可以使得Java虚拟机可以在广泛的平台上被实现。   数据区中的一部分是整个程序共有,其他部分被单独的线程控制。每一个Java虚拟机都包含方法区(method area)和堆(heap),他们都被整个程序共享。Java虚拟机加载并解析一个类以后,将从类文件中解析出来的信息保存与方法区中。程序执行时创建的 对象都保存在堆中。   当一个线程被创建时,会被分配只属于他自己的PC寄存器“pc register”(程序计数器)和Java堆栈(Java stack)。当线程不掉用本地方法时,PC寄存器中保存线程执行的下一条指令。Java堆栈保存了一个线程调用方法时的状态,包括本地变量、调用方法的 参数、返回值、处理的中间变量。调用本地方法时的状态保存在本地方法堆栈中(native method stacks),可能再寄存器或者其他非平台独立的内存中。 
      

  7.   

    感谢楼上,楼上的像是《深入JAVA虚拟机》中的一段。
    其中我对“Java虚拟机总是开始于一个main()方法”,感到迷惑,比如Applet,Swing的程序,并没有main函数,而很多类程序也是在start,run,draw等等这样的函数中开始运行?
      

  8.   

    当然我说的是那些普通的JAVA应用,上面的话也是摘过来的,他只代表了一部分情况,但是这只是为了说明情况而以。主要表明的意图是虚拟机的运行是启始于一个主进程的。我想上面的话就是这个意思,你说呢?
    有很多情况都是没有main方法的,如WEB应用程序,他可能启始于一个客户端对服务器的访问当然,咱们讨论的是虚拟机的机制,对吧。