我真的很困惑Java到底是怎么执行Native Method的.
做为一种高级语言, 何以能够对机器码做任何处理?
想来想去, 就只想到本文所述的这一种方式而已.
本文仅涉及原理方面, 其中猜测成分过重, 以期抛砖引玉, 欢迎大家抛玉.
要弄清楚这个问题, 首先得知道Native Method到底是什么, 它以什么形式存在, 它怎么样被使用。
知道这些, 离问题的答案就近了一步。
native方法 以Windows上鼎鼎大名的DLL作为代表.
源起
Java应用调用SAP RFC传递大量数据时, 随着过程的进行, 该Java应用对其它任务的响应速度变慢, 严重时甚至会导致Java应用core dump。
Java应用和SAP都是跑在各自的Unix服务器上, 所以Java应用调用SAP RFC时, 首先是调用本地的SAP Client, 这个东东在Unix上应该是以动态链接库形式存在的. 我查了下, 在Unix上, 动态链接库习惯以 .so 为文件名结尾(通常还以 lib 开头)。
何为DLL?
DLL是Dynamic Link Library的缩写,意为动态链接库。
比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。 这些子模块和通用模块, 我们倾向于把它们单独各自编译成DLL。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。
DLL vs EXE
从上面可以看出, DLL与EXE只是分工不同而已。
EXE加载后作为进程的主体运行,DLL要加载到一个进程中作为一个模块运行。
他们没有本质的区别。
DLL事实上和EXE文件一样,同属PE格式的执行文件(通俗地讲,机器码。 说明一下, 这里的机器指的是操作系统包装下的机器, 不是指裸机。下同)。只是有个标志位不一样, 用以区分两者。
Java如何调用DLL?
既然DLL为机器码, Java作为一种高级语言,自然对其无能为力。
对于Java调用DLL只能在操作系统级别解释。
Java代码被编译运行在JVM上时,
根据编译原理, 本质上, Java代码最终总要被翻译成机器码,才能运行在操作系统上(
此处也许没说清楚吧, 请看3楼的回帖,详细解释了)。
其实放到操作系统级别来看, JVM也只是运行于其上的一个进程, 而Java应用借助于JVM运行, 就表现为JVM这个进程中的若干个线程, 而调用DLL 就是这个进程中某个线程去调用了存在于代码区的另一段机器码(帖子最后引用了<<WINDOWS核心编程>>, 可以帮助理解)。
所以我们常说的Java调用DLL, 准确地说是JVM调用DLL, 其功能完完全全是由操作系统完成的, 其本质和EXE调用DLL绝无二致。 而JNI在其中的功能,仅仅是告诉操作系统说程序执行到某处时要调用某个动态链接库中的某个函数。
说到这里, 那么关于Java调用DLL时, DLL使用的堆和栈空间是额外申请的, 还是占用的JVM的主存,自然也就不言自明了。
那么, 当Java应用调用SAP RFC传递大量数据时, 会导致Java应用core dump, 也就不难解释了.
原因很简单, JVM上同时运行着大大小小若干个Job, 其内存参数设置不足够大, 陆续为传递过来的数据分配极大量空间而又不能释放,以致于内存耗尽. 如果在调用Native Method过程中JVM能够存活下来, 那么随后Native Method返回时, Java会将返回的数据封装成Java能识别的类型 - Object或其子类, 这就又需要一倍于刚才的空间. JVM在这里挂掉的可能性就大些了。
PS
如若果真如此, 那任何通用型编程语言支持Native Method从实现上来说,简直是再简单不过了。
而Java支持Native Method, 谈不上任何闪光之处。
知识点
引用自<<WINDOWS核心编程>>
在应用程序(或另一个DLL)能够调用DLL中的函数之前,DLL文件映像必须被映射到调用进程的地址空间中。一旦DLL的文件映像被映射到调用进程的地址空间中, DLL的函数就可以供进程中运行的所有线程使用。对于进程中的线程来说,DLL的代码和数据看上去就像恰巧是在进程的地址空间中的额外代码和数据一样。当一个线程调用DLL函数时,该DLL函数要查看线程的堆栈,以便检索它传递的参数,并将线程的堆栈用于它需要的任何局部变量。此外,DLL中函数的代码创建的任何对象均由调用线程所拥有,而DLL本身从来不拥有任何东西。
DLL动态加载:

- 大小: 13.4 KB
分享到:
相关推荐
Jni(Java Native Interface)是sun提供的java与系统中的原生方法交互的技术(在windows\linux系统中,实现java与native method互调)。目前只能由c/c++实现。后两个都是sourceforge上的开源项目,同时也都是基于jni...
Java本身不支持直接调用DLL,但可以通过JNI(Java Native Interface)或者第三方库如JNA(Java Native Access)来实现这一功能。 首先,我们来看JNI。JNI是Java平台标准的一部分,它为Java程序员提供了一种安全、...
在Java中调用DLL文件主要通过Java Native Interface (JNI)、JAWINJNative和JNA等技术来实现。这些技术允许Java程序与本地代码进行交互,从而实现对DLL文件的调用。 #### JNI (Java Native Interface) JNI是Java...
其中一种方案是使用Java Native Access (JNA) 来调用通过C++封装的C# DLL文件。 **步骤详解:** **1. 创建C# COM组件:** - **新建项目:** 在Visual Studio中创建一个新的类库项目,并命名为`COMTest`。 - **...
通过JNI,Java程序可以调用C/C++函数,同时C/C++也可以调用Java的方法。以下是一些关于JNI和`native`关键字的核心知识点: 1. **JNI头文件生成**:在编写Java类并声明`native`方法后,我们需要使用`javah`工具生成...
Native方法是Java编程语言中的一个特性,允许Java代码调用非Java代码(通常是C或C++编写的),这为Java应用程序提供了一个与本地操作系统和其他原生库交互的接口。这种能力对于那些需要高性能或特定平台功能的应用...
Java Native Access (JNA) 是一个流行的开源框架,它允许Java代码直接调用本机库函数,而无需编写JNI(Java Native Interface)代码。本文将详细介绍如何使用JNA在Java中调用第三方DLL以及提供的DEMO示例。 首先,...
4. **调用函数**:现在你可以像调用Java方法一样调用DLL中的函数了。 示例代码: ```java public interface MyDLL extends Library { int add(int a, int b); } MyDLL dll = (MyDLL) Native.loadLibrary("mydll",...
通过理解JNA的工作原理,以及如何定义接口和结构体来映射原生函数,你可以轻松地在Java中调用`Kernel32.dll`或其他系统库中的函数。记住,合理使用并注意安全性和性能优化,是成功使用JNA的关键。
Java本身并不直接支持调用本地DLL库,但通过Java Native Interface (JNI) 或第三方库如JNA(Java Native Access)可以实现。在这个项目中,开发者可能使用了JNA,因为它允许更简洁的API和无需编写C语言的头文件和...
首先,了解Java调用SPSS的基本原理:IBM SPSS Statistics提供了一套名为SPSSINC Java插件的API,它允许Java程序直接与SPSS会话进行交互。这个插件包含了一系列Java类,通过这些类,开发者可以创建、读取、写入和执行...
在Java编程环境中,有时我们需要利用C++编写的DLL动态链接库功能,特别是在处理底层系统调用或硬件交互时。本文将详细介绍如何通过Java Native Access (JNA) 库来实现Java调用DLL动态库,以"NetSdk.dll"为例进行实战...
在Java中调用DLL(Dynamic Link Library)文件,可以使用Java的本地方法接口(JNI,Java Native Interface)来实现。JNI允许Java程序与本地代码进行交互,从而实现跨平台的功能。
Java调用Chrome浏览器内核是开发桌面应用时一个常见的需求,尤其在需要嵌入Web页面或者与Web内容交互的场景下。CEF(Chromium Embedded Framework)是一个开源项目,它允许开发者将Google Chrome的Blink渲染引擎和V8...
首先,理解Delphi 7调用Java接口的基础原理。这种通信通常依赖于Java的本地接口(JNI,Java Native Interface),它允许Java代码调用C/C++代码,而Delphi代码可以编译为C++兼容的库。因此,Delphi通过JNI桥接,可以...
这种技术通常依赖于Java Native Interface (JNI),它允许Java代码直接调用本地(如C++)代码,反之亦然。下面我们将深入探讨如何通过JNI在Java中调用C++类对象以及涉及的关键知识点。 首先,我们需要理解JNI的概念...
4. 调用C++函数:现在,你可以像调用Java方法一样调用C++库的函数了。 ```java int result = lib.downloadRecording("recording.mp4", 1642404000, 1642407600); ``` 5. 错误处理:由于JNA是直接调用本地代码,错误...
Java本身并不直接支持调用C++代码,但可以通过JNI(Java Native Interface)来实现。JNI提供了一种方式让Java代码能够调用本地(native)代码,包括C和C++。这需要编写一个JNI头文件,定义C/C++函数的原型,然后编写...
在探讨Java调用带有JSON参数的WebService之前,我们首先需要了解几个关键的技术概念:Java、JSON以及WebService。 Java是一种广泛使用的编程语言,它具有面向对象、跨平台、多线程以及健壮性等特点。Java在企业级...
1. **Java Native Interface (JNI)**:由于大华SDK可能是用C或C++编写的,Java后端需要通过JNI来调用这些原生库。JNI允许Java代码直接调用本地(非Java)代码,实现跨语言交互。 2. **大华SDK**:大华提供了一套...