3

我的申请由两部分组成 -

Java中的一些GUI逻辑。本机代码(主要是 Delphi)——GUI 实现本身。

Java 使用本机代码进行琐碎的操作,例如打开窗口和响应用户输入事件 - 实现是通过 JNI 完成的。

我有兴趣将双方划分为不同的进程 - 在不挂 gui 的情况下在它们之间实现 IPC 的最佳方法是什么?我倾向于 TCP 套接字或共享内存,但在我深入研究之前,我很想听听一些意见。性能和简单的实现是我主要关心的问题。

提前致谢。

4

3 回答 3

3

如果您的问题与内存消耗有关

如果您的内存不足(正如您的评论所建议的那样 - 但您应该在主要问题中更好地写下这一点:您提供的详细信息越多,您得到的答案就越好)。

为什么要混合 Java 和 Delphi?Java 可能不适合处理超过 1 GB 的内存,因为它用于常见任务的内存消耗较高,而且它的内部 GC。即使您以 64 位运行 JVM,您也将面临新的扩展问题:您必须编写非常具体的代码来使用 Java 处理巨大的内存。

公平地说,问题不是来自 Delphi,而是来自 Java 内存消耗。因此,恕我直言,您应该更好地使用本机代码对数据层进行编码。Java 可能会增加您的问题。

您可以:

  • 使用Free Pascal 编译器从 Delphi 代码编译 64 位库,然后从主 32 位 Delphi 应用程序或使用 JNI 的 Java 调用它,使用Memory Mapped 文件作为 bridge
  • 改变您访问数据的方式。您可能不需要一次拥有所有这些千兆字节的数据。您可以将它放在磁盘上,然后通过索引访问它,该索引将保留在 RAM 中。如果您使用 Delphi,您应该使用自己的文件处理(您可以使用我们的BigTable 库之类的东西进行存储和索引访问),或者使用数据库(甚至SQlite3 也能够处理 GB 的数据,因为它的限制约为 140 TB ,具有仅检索数据的 SQL 功能)。
  • 如果你真的需要留在 Java 中,你可能会使用一些 DB 而不是普通的内存结构。您可以从 Java 或纯 Java DB 使用 SQLite。我怀疑它会减少你的内存消耗。

主要方法是:只在内存中保留需要的内容,并使用 Map/Reduce 算法或某种索引。

如果您的问题是在 Java 和 Delphi 之间混合 GUI

从我的实验来看,这可能很困难,因为 JNI 倾向于使用自己的线程,而 VCL 期望它的所有进程都在主线程中运行。

所以你可以:

  1. 创建一些 Delphi 方法,在从 JNI 调用时运行 VCL Synchronize 方法以更新屏幕。
  2. 依靠 Windows GDI 消息通信,即在 Delphi 代码中创建您自己的 WM_USER* 处理程序,然后通过发送一些低级 PostMessage 或 SendMessage API 从您的 Java 代码刷新屏幕内容。按照设计,这将是线程安全的。
  3. 使用无状态方法:我非常喜欢它。就像在 HTTP 中一样,您的用户界面将充当客户端,并会定期向数据层(充当服务器)请求刷新数据。所有这些过程都将保留在主线程中,并且可以通过 Timer 轻松完成。使用计时器,每次刷新有 500 毫秒的周期就足够了,您的主应用程序将保持反应状态。

在所有情况下...

对于 IPC,内存映射文件比套接字快,但 GDI 消息在处理少量数据时是理想的。套接字是很好的候选者,并且在本地机器上也很快:如果传输的数据量只有几 KB(例如高达 1 MB),内存映射文件的小开销将不会很明显;如果您需要创建应用程序的轻客户端版本,它仍然可以工作。

于 2011-06-20T06:27:21.843 回答
1

您回答的问题取决于您的要求(假设您有充分的理由以这种方式划分应用程序):

如果您需要执行“琐碎”的任务,即不需要太多的数据传输,那么使用套接字可能会更好。尽管如此,您仍需要创建一个协议,例如尊重字节顺序。另请注意,传输数据会减慢您的 gui 响应速度。

如果您需要传输大量数据,使用共享内存可能会更高效。请注意,这里您需要自己进行簿记,这是由 tcp 实现完成的(例如发送/接收缓冲区)。使用这个需要协议的问题变得更糟。

于 2011-06-19T22:08:11.060 回答
0

如果您想要一个简单的实现,那么不要将应用程序分成两个进程。就性能而言,这不是问题,但是您在单个应用程序所需的复杂性之上增加了一个复杂度。您需要有充分的理由将应用程序划分为多个进程,以克服使用此架构交付相同功能所花费的时间和精力。

于 2011-06-19T23:59:07.193 回答