Меню Рубрики

Как написать dll на java

C# to Java (вызов C# dll из Java)

Доброго времени суток!
Помучив немного хабра поиск не нашел подобных тем, в связи с чем создал свою.

Немного лирики:
Имеем шарповскую библиотеку, в которой лежат необходимые для работы методы. Необходимо этими методами воспользоваться из Java программы.

Пример первый

Сначала покажу простой пример.
Имеем примитивную dll на шарпе, назовем ее SharpClass:

Будем собирать этот класс в сборку:
Открываем командную строку, и прописываем такую команду (предварительно нужно зайти в директорию с нашим SharpClass.cs файлом): csc \t: module SharpClass.cs. Если команда не работает, то перед ее запуском нужно выполнить бат-файл, у меня он находится здесь — C:\Program Files\Microsoft Visual Studio 9\VC\bin\vcvars32.bat
После выполнения сей процедуры мы получим файл SharpClass.netmodule, находящийся в одной папке с исходником.

Для связи между .NET и JVM нужен враппер (обертка для получения unmanaged кода). Создадим обертку из с++ с использованием явовской библиотеки jni.h и майкрософтовской библиотеки mscorlib.dll
Создаем с++ обертку:

После написания этого кода необходимо указать ссылку на mscorlib.dll. Для этого заходим в настройки проекта и сначала находим General, где в пункте Common Language Runtime Support выбираем Common Language Runtime Support, Old Syntax (/clr:oldSyntax), после этого жмем References (ссылки) и добавляем новую — во вкладке .NET будет искомая dll (так было в VS2005).

И последний хедер генерируется при помощи Java из командной строки запуском команды — javah -jni «имя класса без кавычек и без .class» (создавать его естественно нужно после компиляции ява программы, иначе сам класс просто не появится). В файлах 1.h и 2.cpp код также взят из последнего хедера.

После этого весь c++ проект строится в dll. Назовем его HelloWorld.dll.

Теперь переходим к Яве. Вот простой код для вызова нашей HelloWorld.dll:

Вот собственно все готово. Ну и наш SharpClass.netmodule также необходимо перенести в папку с загружаемой сишной dll.

Пример второй

В первом примере рассматривался простой случай просто с выводом текста на экран. Сейчас рассмотрим случай, когда функция на C# принимает параметры и возвращает значение.
C# класс:

Java приложение, использующее этот класс:

После этого создаем хедер для с++ с помощью команды, описанной в первом примере.
Далее создаем с++ обертку, которая таскает переменные из одного конца в другой :). Будет 3 файла — wrapper.cpp, CSharpToJava.cpp, Main.h (последний получается выполнением команды javah -jni над явовским классом)

Заключение

Ну вот собственно и все. Данный код писал и испытывал 2 года назад, а сюда все никак руки не доходили написать. Когда разбирался с этой задачей, пытался просить помощи на одном форуме. Пока помощи просил, сам немного разобрался и написал свое решение.

Источник статьи: http://habr.com/ru/post/92924/

JNI: как конкретно создать dll для вызова её из java-кода

Базовые технологии Java /

Другие технологии

Во всех статьях, которые я нашёл, описано так, будто я знаю C/C++/Visual C++.
Я всё сделал более менее по этому примеру
http://www.codeproject.com/KB/java/jnibasics1.aspx

Однако мне выдаётся ошибка java.lang.UnsatisfiedLinkError .

Какие есть средства, чтобы понять точно, в чём дело и почему не находится метод в библиотеке?
Если есть более подробные статьи про создание проекта в Visual C++, дайте ссылку.

Я создавал проекты типов MFC DLL и simple DLL — проекты в Visual C++ компилируются, dll собирается, но метод не находится.

«Во всех статьях, которые я нашёл, описано так, будто я знаю C/C++/Visual C++. «

JNI он как бы намекает на то, что вы хоть как-то знакомы с C++

«Во всех статьях, которые я нашёл, описано так, будто я знаю C/C++/Visual C++. «

JNI он как бы намекает на то, что вы хоть как-то знакомы с C++

Наоборот, в том то и прелесть, мне вообще о C нужны самые минимальные знания. Сама по себе библиотека dll уже написана теми, кто знает C. Мне нужно просто использовать функцию оттуда.
Всё, что я хочу знать, это как создать переходную dll.

и вообще StackTrace покажите

и вообще StackTrace покажите

Я понял, что не подцепляется метод. Я не понимаю почему.
Вот стектрейс. Я его не привёл, так как он очень общий. Ну если что-то сможете из него увидеть, будет здорово.

У меня такой эксепшен летит — когда, например. параметры не того типа передаю в метод dll (хотя в данном случае вроде совсем простой метод).

Далее loadlibrary должен осуществляться в статическом инициализаторе первого загружаемого класса. и т.д. — мелочей таких может быть много — не поленитесь поработать по инструкции — даже пусть вызвать какую-нить простую dll. Тем более, что библиотеку писал другой человек — он там что угодно мог намутить.

У меня такой эксепшен летит — когда, например. параметры не того типа передаю в метод dll (хотя в данном случае вроде совсем простой метод).

Далее loadlibrary должен осуществляться в статическом инициализаторе первого загружаемого класса. и т.д. — мелочей таких может быть много — не поленитесь поработать по инструкции — даже пусть вызвать какую-нить простую dll. Тем более, что библиотеку писал другой человек — он там что угодно мог намутить.

Я всё делал по инструкции. В этом примере я эту библиотеку никак не использую. Я просто самую простую функцию пытаюсь вызвать из java.

Источник статьи: http://javatalks.ru/topics/25239

Получаем версию файла (exe, dll) с помощью java

Столкнулась я с такой проблемкой — как получить версию файла (exe и dll) на java. Ведь обычными стандартными средствами определить это нельзя, а только лишь можно узнать размер, дату последней модификации и некоторые другие свойства файла. Это описано тут.
Покопавшись на форумах и всё хорошенько прогуглив — нашла два таких выхода — JNI и JNA. Остановилась на втором варианте, так как на С++ писать специальную dll ну уж очень не хотелось, хотелось всё решить с помощью java и обращаться напрямую к version.dll (C:\WINDOWS\system32).
В итоге решение сводится к такой связке GetFileVersionInfo — GetFileVersionInfoSize — VerQueryValue. Долго пришлось поразбираться с функцией VerQueryValue — сложность была в том, что версии файлы зависят от языка и необходимо было хитрым способом получить LANGANDCODEPAGE. В итоге получился такой класс:

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import java.io.IOException;

/**
*
* @author samozvanka
*/
public class Win32GetFileInformation
<
//+ declare before using
private static byte [] Hexhars = ««0123456789abcdef» .getBytes();

public String FileVersion;
private String LanguageCodePage;
private PointerByReference InfoData;

public interface Win32VersionDLL extends StdCallLibrary
<
Win32VersionDLL INSTANCE = (Win32VersionDLL) Native.loadLibrary(
«Version» , Win32VersionDLL. class );

Integer GetFileVersionInfoSizeA( String FilePath, IntByReference Handle);

Boolean GetFileVersionInfoA( String FilePath, int Handle, int InfoSize,
PointerByReference InfoData);

Boolean VerQueryValueA(PointerByReference InfoData,
String VersionInformation, PointerByReference VersionData,
IntByReference DataSize);
>

public void Win32GetFileInformation( String FilePath) throws IOException
<
IntByReference unusedParam = new IntByReference();

int infoSize = Win32VersionDLL.INSTANCE.GetFileVersionInfoSizeA(FilePath, unusedParam);
if (infoSize == 0)
<
throw new IOException( «File does not exist or has no information.» );
>

this .InfoData = new PointerByReference();

Boolean success = Win32VersionDLL.INSTANCE.GetFileVersionInfoA
(
FilePath,
unusedParam.getValue(),
infoSize,
this .InfoData
);

//+ Assert(success, «GetFileVersionInfoA in Win32GetFileInformation is failed»)

PointerByReference versionDataByRef = new PointerByReference();
IntByReference dataSize = new IntByReference();
Pointer versionDataPointer = null ;

// Retrieve the language information
success = Win32VersionDLL.INSTANCE.VerQueryValueA
(
this .InfoData,
«\\VarFileInfo\\Translation» ,
versionDataByRef,
dataSize
);

//+ Assert(success, «VerQueryValueA in Win32GetFileInformation is failed»)

System. out .println( «DataSize.getValue() = » + dataSize.getValue());

versionDataPointer = versionDataByRef.getValue();
byte [] codePageBytes = versionDataPointer.getByteArray(0, dataSize.getValue());
byte BSwap;
// swap 0 1 and 2 3
BSwap = codePageBytes[1];
codePageBytes[1] = codePageBytes[0];
codePageBytes[0] = BSwap;
BSwap = codePageBytes[3];
codePageBytes[3] = codePageBytes[2];
codePageBytes[2] = BSwap;
// got 1,0,3,2

this .LanguageCodePage = decode(codePageBytes).toUpperCase();

//// Retrieve file information
this .FileVersion = QueryValue( «FileVersion» );

System. out .println( «FileVersion = » + this .FileVersion);

private String QueryValue( String ValueName)
<
IntByReference dataSize = new IntByReference();
PointerByReference versionDataByRef = new PointerByReference();
Pointer versionDataPointer = null ;
Boolean success = Win32VersionDLL.INSTANCE.VerQueryValueA
(
this .InfoData,
«\\StringFileInfo\\» + this.LanguageCodePage + » \\ » + ValueName, //»
versionDataByRef,
dataSize
);

//+ Assert(success, «VerQueryValueA in Win32GetFileInformation is failed»)

versionDataPointer = versionDataByRef.getValue();
if (versionDataPointer == null )
<
return «» ;
>
else
<
versionDataPointer = versionDataByRef.getValue();
return versionDataPointer.getString();
>
>

private static String decode( byte [] encodedString)
<
StringBuilder result = new StringBuilder (2 * encodedString.length);

for ( int i = 0; i int v = encodedString[i] & 0xff;

result.append(( char ) Hexhars[v >> 4]);
result.append(( char ) Hexhars[v & 0xf]);
>

return result.toString();
>
>

* This source code was highlighted with Source Code Highlighter .

Вдруг кому пригодится. И если есть другие какие то несложные реализации этого, то хотелось бы их узнать.

Источник статьи: http://habr.com/ru/post/93028/

Как подружить Java с системой через написание dll на C++

Окей. Как мне стало известно из изучения Java, что по сути Java не общается с самой операционной системой, она посылает запрос в JVM и обрабатывает его. Например получение Jav’ой доступу к принтеру. Но! Java не может получать доступ к регистру, автозапуску и прочим вещам. Окей я не буду вдаваться в подробности зачем, но просто есть необходимость.

Например у меня есть задача, определена точно ОС — Windows. И мне необходимо «хукать» нажатия клавиатуры, или производить эти нажатия самой программой. Я нашел решение — написание dll библиотеки на C++. Но как мне ее написать. Если мы пишем код на C++ подключая библиотеку windows.h для работы с winapi. И при этом скомпилированный этот код в виде библиотеки подрубаем в Java код. Ничего не потеряется?

1 ответ 1

Из JVM есть несколько дверей в операционную систему — JNI, JNA и JNR. JNI (Java Native Interface) — самый старый и чаще всего используемый способ взаимодействия с нативным кодом. Его минус в том, что он требует от программиста знания C/C++ и хорошего понимания принципов работы виртуальной машины. JNA (Java Native Access) — это надстройка над JNI изолирующая программиста от низкоуровневых деталей за счёт использования рефлексии и libffi. А где рефлексия, там низкая производительность и высокое количество рантайм ошибок. В JNR (Java Native Runtime) рефлексию заменили генерацией байткода, что существенно увеличило производительность. Это относительно молодой проект, я в нём ещё не копался и сказать ничего не могу. А вот пример примитивного кейлогера с использованием JNI показать могу.

Компилируем командой javac -h . Snitch.java . Ключ -h указывает в каком каталоге создать заголовочный файл с определениями нативных методов.

Компилируем c’шный исходник в snitch.dll, запускаем нашу программу командой java Snitch и убеждаемся, что в C:\Temp\keyboard.txt регистрируются нажатые клавиши.

Чуть более подробно о процессе компиляции и объявлениях JNI-методов можно посмотреть в другом моём ответе.

Источник статьи: http://ru.stackoverflow.com/questions/465834/%D0%9A%D0%B0%D0%BA-%D0%BF%D0%BE%D0%B4%D1%80%D1%83%D0%B6%D0%B8%D1%82%D1%8C-java-%D1%81-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BE%D0%B9-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-dll-%D0%BD%D0%B0-c

Как подружить Java и C++. Часть первая

Как вы, наверное, уже догадались, речь пойдет о JNI. Для тех, кто не знает что это, объясняю: JNI (или java native interface) — это такая штука, которая позволяет делать вызовы нативного кода из java машины и наоборот.

Зачем это может потребоваться? Есть несколько причин: необходимость использовать код, который уже написан для нативной платформы, необходимость реализовать что-то такое, что невозможно сделать с помощью одной JVM (например, работа с какими-нибудь специфическими железками), ну и ускорение выполнения критических кусков кода (правда, это весьма спорный момент).

Как работает JNI

Допустим, у нас есть какой-то java класс из которого надо вызвать метод, написанный на c++ и находящийся в динамически связываемой библиотеке (например, в windows это будет dll). Что мы должны для этого сделать?

Для начала мы объявляем метод какого-нибудь класса как native. Это будет означать, что JVM при вызове этого метода будет передавать управление нативному коду.

Затем, нам надо загрузить нативную библиотеку. Для этого можно вызвать System.loadLibrary(String) , которая принимает в качестве параметра имя библиотеки. После этого вызова библиотека будет загружена в адресное пространство JVM.

Теперь, представим, что у нас есть следующий java класс:

public class NativeCallsClass
<
static
<
System . loadLibrary ( «megalib» ) ;
>

native public static void printOne ( ) ;
native public static void printTwo ( ) ;
>

Здесь мы, для удобства, вынесли loadLibrary() в static область класса.

Допустим, теперь, что мы вызываем NativeCallsClass.printOne() . Тогда JVM будет искать в библиотеках метод со следующим именем: Java_my_mega_pack_NativeCallsClass_printOne(. ) .

Объявление JNI функций в C++

Мы написали класс на java, у которого есть методы, помеченные как native. Теперь нам надо создать хедеры с объявлениями функций C++, которые мы хотим вызывать.

Конечно, можно написать их вручную. Но есть более удобный метод:

Мы компилируем класс, а потом используем утилиту javah. После этого у нас появится файл, который называется my_mega_pack_NativeCallsClass.h. Это и есть наш хедер. Выглядит он примерно так:

/* DO NOT EDIT THIS FILE — it is machine generated */
#include
/* Header for class my_mega_pack_NativeCallsClass */

#ifndef _Included_my_mega_pack_NativeCallsClass
#define _Included_my_mega_pack_NativeCallsClass
#ifdef __cplusplus
extern «C» <
#endif
/*
* Class: my_mega_pack_NativeCallsClass
* Method: printOne
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printOne
( JNIEnv * , jclass ) ;

/*
* Class: my_mega_pack_NativeCallsClass
* Method: printTwo
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printTwo
( JNIEnv * , jclass ) ;

Самое главное здесь — это сигнатуры 2х функций: Java_my_mega_pack_NativeCallsClass_printOne(JNIEnv *env, jclass myclass) и Java_my_mega_pack_NativeCallsClass_printTwo(JNIEnv *env, jclass myclass) .

Их-то нам и надо реализовать. Для начала разберемся с их сигнатурами. env — это интерфейс к виртуальной машине. Все операции с JVM выполняются с помощью него. Позже мы разберем это подробнее. myclass — это идентификатор java класса, у которого есть метод native, отождествленный с этой функцией, то есть в нашем случае это NativeCallsClass . Обратите внимание, что jclass в качестве второго параметра передается тогда, когда метод объявлен как static. Если бы он был обычным методом, то нам бы передавался jobject, который бы идентифицировал объект, метод которого мы вызвали (фактически это аналог this).

Нам остается только реализовать эти функции:

#include
#include «my_mega_pack_NativeCallsClass.h»

JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printOne ( JNIEnv * env, jclass myclass )
<
std :: cout «One» std :: endl ;
>

JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_printTwo ( JNIEnv * env, jclass myclass )
<
std :: cout «Two» std :: endl ;
>

Передаем данные в нативный код и обратно

public class NativeCallsClass
<
static
<
System . loadLibrary ( «megalib» ) ;
>

native public static int inputInt ( ) ;
native public static void outputInt ( int v ) ;
>

JNICALL Java_my_mega_pack_NativeCallsClass_inputInt ( JNIEnv * , jclass ) ;
JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_outputInt ( JNIEnv * , jclass, jint ) ;

#include
#include «my_mega_pack_NativeCallsClass.h»

JNIEXPORT jint JNICALL Java_my_mega_pack_NativeCallsClass_inputInt ( JNIEnv * env, jclass myclass )
<
int ret;

JNIEXPORT void JNICALL Java_my_mega_pack_NativeCallsClass_outputInt ( JNIEnv * env, jclass myclass, jint v )
<
std :: cout v std :: endl ;
>

Подводим итог

Итак, в первой части мы рассмотрели, как работает JNI, как писать java классы, с помощью которых можно осуществлять вызовы нативного когда и как писать C++ функции, вызываемые через JNI. В следующей части (или частях) мы рассмотрим взаимодействие с JVM из C++ кода, работу с классами, объектами полями и методами, создание proxy классов java, которые бы представляли C++ классы и запуск JVM из C++ кода.

Естественно, продолжение будет только в том случае, если это кому-то интересно 🙂

Редакторский дайджест

Присылаем лучшие статьи раз в месяц

Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.

Похожие публикации

Удобоваримый вызов Java методов из нативного кода

Java Native Interface. C++. Linux. Первые шаги

Обзор зарплат программистов Java/C++/C#/Delphi

Средняя зарплата в IT

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 53

Интересно узнать про методику выноса части функционала в C++ модуль.
Например, мне нужно выполнить ресурсоемкую операцию с изображением, и я не хочу это делать средствами Java.

Допустим, я подаю C-методу на вход картинку в виде массива байтов, Сишный код выполняет операцию с изображением и возвращет мне обратно массив байтов, дальше, средствами Джавы, я отображаю ее пользователю.

Возможно ли такое?
Стоит ли шкура выделки? Могу ли я таким образом повысить производительность своего приложения?

Конечно возможно. Как передавать данные со структурой сложнее, чем у примитивных типов, я опишу в следующей части.

На счет вопроса, можно ли таким образом получить ускорение. Далеко не обязательно. В java есть JIT, который неплохо делает свою работу. С другой стороны, управляя памятью вручную, мы снимаем нагрузку с GC, что может дать некоторое ускорение. Вообщем, нужно хорошо понимать, что вы делаете 🙂

Мне кажется, не стоит передавать изображение в виде массива байтов. Лучше записать его во временный файл и передать С++ лишь имя файла (да и вообще в джаве весь файл целиком не стоит считывать, имхо). По скорости это не будет особо влиять на нормальных фс (типа xfs, где если у вас много оперативки — файл останется в RAM некоторое время).

Плюсы — не забивается память (а точнее умно управляется фс), скорость максимальная.

По идее должна справляться, но в любом случае всегда можно жестко указать что файл будет храниться в RAM’е. Такой-себе юникс-вей (не мешают ведь возможности фс делать виртуальную фс для устройств).

Насколько я понимаю, с потоковым видео вообще это вещь хорошая (чтоб поток шёл в файл, а программка уже этот файл обрабатывала), ведь ОС справится куда лучше с нормальным получением потока в файл при хороших нагрузках чем ваша программа с двумя задачами сразу (и получение и обработка). И если программа чуть (на секунду) зависнет, ос, скорее всего, с потоком справится нормально.

p.s.: это так, «мысли вслух», подобным не занимался, потому интересно от «практиков» услышать как оно на самом деле надо делать)

Да вы что, с чем ОС справится лучше?! Лучше чего?
Файловая система — особенно в многозадачной среде — опасный союзник! У вас нет никаких прогнозов на скорость доступа к ней, какой тут реалтайм. Сейчас ваш файл буферезирован, а через секунду кто-то запросил памяти и буфер слит. И ваш код ждет данных неивестно сколько — как совпадут звезды, фрагментированность фс, загруженность очереди доступа к ней и еще бог знает сколько факторов.
Если файловая система живет в ядре — с большой вероятностью практически каждая операция доступа к ней — переключение в режим ядра, что весьма небыстро (вы все еще хотите реалтайма? =) ). От этого спасает опять-таки буферизация, но вы ведь память экономить хотели?

В общем говоря, если вам нужна скорость и детерменнированность — данные нужно передавать только в памяти. Нужна экономия — ищите способ минимизировать эти данные — передавать их блоками, слайсами, фреймами, как угодно.

Не вижу разницы между хранением потока в оперативки и memory mapped file ни по скорости ни по сливу на жесткий диск (или я ошибаюсь?)

А почему хочется такого (с файлом)? Очень просто: к примеру, можно задать входной поток подпрограмме как файл (типа внешний API для тестирования в том числе уже готов).

Или все-таки эти файлы в оперативке которые куда медленнее кидания буферами между модулями?

> Если вам важна производительность — быстрее блока памяти вы ничего не придумаете.

Более чем согласен. У меня просто в другом чуть вопрос. На сколько я понял, оно отлично преобразует типы и классы из джавовских в C++’ные. Скорее всего это делается клонированием? Или я не прав?

Тоесть когда вы передаёте этот самый блок памяти, C++ имеет доступ именно к нему (без излишеств?) Если да — всё ясно, вы правы насчет производительности 🙂

При использовании C++ для написания JNI методов нужно иметь в виду, что могут возникать C++ exceptions, которые не мог быть обработаны JVM, так как используется C ABI. Поэтому нужно корректно перехватывать эти исключения и либо конвертировать их в Java исключения, либо корректно завершать работу JVM. При использовании чистого C такой проблемы нет.

Другой важный момент — это то, что Java exception, брошенный в нативном методе, не прерывает работу нативного метода в точке выброса exception.

Когда имеет смысл использовать JNI:

— имеется только нативная версия библиотеки с каторой нужно работать
— нужен доступ к ресурсам, которым JVM не предоставляет доступ или доступ реализован очень плохо

На текущий момент JVM JIT генерирует очень хороший код и задача написать быстрый JNI код — это нетривиальная задача, прикручивание в лоб обычно никакого прироста может не дать. У меня есть живые примеры, когда к нативной библиотеке, которая в 5 раз быстрее соотвествующей чистой Java библиотеки, прикручивали JNI интерфейс, итоговая производительность была всего лишь чуть-чуть больше чистой Java. Накладные расходы по JNI вызовам очень большие, поэтому желательно уходить в натив надолго, слишком частые переключения контекстов испольнения значительно снизять производительность. Еще один факт из жизни, чем сложнее данные которые нужно передовать между Java и нативом, тем медленее все работает. Все работает достаточно быстро при использовании примитивных типов, массивов примитовного типа и String.

Очень-очень большие минусы JNI кода:

— JNI код — это огромная security дыра в Java security-модели, JVM не имеет никаких средств по контролю JNI кода и JNI код может делать что угодно, в том числе получать доступ к приватным данным.
— Утечки памяти. Память которая выделяется в JNI коде, за исключение Java объектов созданных в нативе, выделяется в общем heap приложения, а не в Java-heap. В Java нет деструкторов, поэтому может возникнут ситуация, когда что-то навыделялось в нативе и уже не нужно, но оно не освобождается. Пример:

Пусть у нас есть Java объект, состоящий из Java данных и C++ данных (создаем в нативе С++ объект и храним handle на него в Java объекте), удаление C++ объекта помещаем в метод finalize, так как вызов finalize метода не дерминирован, то у нас возникают утечки памяти. С точки зрения GC проводить сборку мусора не нужно, так как Java-heap имеет достаточно места.

Еще одна головная боль — это отладка JNI кода, приходится использовать два дебагера: Java кода и нативного кода. Вроде для Eclipse есть какой-то дебагер который позволяет отлаживать как Java код, так и JNI код.

Согласен со всем. Просто нужно понимать, что делаешь и когда это нужно применять.

Кстати, добавлю. Оверхед может появиться даже при передаче массивов примитивного типа и строк, потому что JVM в некоторых случаях может решить, что их нужно скопировать.

Источник статьи: http://habr.com/ru/post/49660/


0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии