SlideShare ist ein Scribd-Unternehmen logo
1 von 27
Downloaden Sie, um offline zu lesen
Building
High-Performance
Android
Applications in
Java & C++
Kenneth Geisshirt
kg@realm.io
Realm Inc.
@realm
http://github.com/Realm/
http://realm.io/
JD Hancock: Reign of The Android. http://bit.ly/1GN8vmg
Today’s goal
• Android development is not
just Java
• C and C++ can speed
apps up - and reuse old
legacy code
• Learn a few tricks when
working with Java Native
Interface
Swen-Peter Ekkebus: Goal! http://bit.ly/1x1suYm
Avinash Sharma: http://bit.ly/1aRorcH
Agenda
• About me and Realm
• Example: estimating π
• Java Native Interface
• Building
• Memory
• Java types, arrays, and strings
• Logging and profiling
Exploratorium. After Dark: Time http://bit.ly/1aSQxo0
About me
• Lives in Tårnby, a suburb of Copenhagen
• Education
• M.Sc. in computer science and chemistry
• Ph.D. in soft condensed matter
• Commodore 64 was my first home computer
• UNIX user, developer, and sysadmin since 1990
• BSD UNIX (Tahoe), Solaris, Linux, Irix, OS X, …
• Tech writer and reviewer
• Packt Pub, O’Reilly, Linux Magazine, Alt om DATA
• Currently working for Realm as developer
Leo Reynolds, https://www.flickr.com/photos/lwr/
Shane Doucette, https://www.flickr.com/photos/lwr/
About Realm
• Founded in 2011 (YC S11)
• Funded by Khosla, Scale, …
• Distributed work force
• Copenhagen: 8 developers
• San Francisco: 4 developers
+ marketing + management
• Developers in Århus, Perth,
Berlin, Tokyo, and Seoul
• New database written from scratch
• Cross-platform core in C++
• Full ACID
• Fast, low footprint, easy to use
• Apache License 2.0
W
e
are
hiring
Java Native Interface (JNI)
• Use C or C++ in your apps → no JIT needed as
always machine instructions
• Access to system calls (like mmap())
• Almost no limits on memory usage
• OpenGL programming
Alan Bates. Good Times http://bit.ly/1BXX7FN
JNI disadvantages
• C and C++ memory
management → easy to crash
your app
• And debugging across
languages is hard
• Bionic C library isn’t the GNU C library
• Doing a native call is expensive (in time)
• Cumbersome to use non-NDK libraries
Rocher: That_Sux http://bit.ly/1BdGNhJ
Use cases
• AndEngine (2D Game Engine)
http://www.andengine.org
• ImageMagick for Android
https://github.com/paulasiimwe/Android-ImageMagick
• LevelDB for Android
https://github.com/litl/android-leveldb
• Support Vector Machine for Android
https://github.com/cnbuff410/Libsvm-androidjni
Estimating π
Estimating π using dart
• Throw arrows at random
• Nhit/N = A/4 (quarter of a circle)
• A = π·r2 (area of a circle)
• π = 4·Nhit/N (with r = 1)
Bogdan Suditu: Darts. http://bit.ly/18jCExj
for i = 1,..,N
x = random(0, 1)
y = random(0, 1)
if (sqrt(x·x+y·y) < 1)
Nhit = Nhit +1
π = 4·Nhit/N
Example: the app
Android app to estimate π
• pure Java implementation
• pure C++ implementation
• mixture of Java (iterations) and
C++ (random number
generator)
• https://github.com/kneth/
AndroidCalcPi
Example: the classes
Random number generator
• Constructor with seed
• Method uniform() to
return random number
between 0.0 and 1.0
π estimator
• Constructor with
number of iteration
• Method estimate() to
calculate the value of π
Quinn Dombrowski: Pi http://bit.ly/1Kz55cp
jeramiah.andrick. My random number generator http://bit.ly/1wbTbP2
Organising your files
• Place C/C++ files in app/src/main/
jni/src
• Add ndk.dir to local.properties
• Add an ndk section to your app’s
build.gradle
ndk {
moduleName "calcPi"
cFlags "-std=c++11 -fexceptions"
stl "gnustl_shared"
}
add to the android section
(currently deprecated)
Building and loading your native
code
• Automatically build for all
supported architectures (ARM,
ARMv7, ARM64, MIPS, MIPS64,
x86, x86-64)
• Android only installs the relevant
architecture
• Load native code early (main
activity’s onCreate)
System.loadLibrary("calcPi");
The module name (from build.gradle)
Thomas Hawk: Loading Zone http://bit.ly/1MoBk9S
Calling a C++ function
• Use Java’s native keyword in
the signature
• Implement the function in C++
• Use a long to store the C++
pointer when you creates an
object
lamont_cranston: call center http://bit.ly/1A4JlK5
native long nativeCreate(long iterations);
native double nativeEstimate(long nativePtr);
Tell the Java compiler
it’s a native function
Returns a pointer
(a C++ object) Operates on a C++ object
Generate header files
• .class files contain information
about native calls
• javah can extract signatures and
generate C/C++ header files
Paul: Generator Room Door http://bit.ly/1C3SSs7
!/bin/bash
# Setting up
CLASSDIR="$(pwd)/../app/build/intermediates/classes/debug"
JNIDIR="$(pwd)/src"
# Generate the headers
(cd "$CLASSDIR" && javah -jni -classpath "$CLASSDIR" -d "$JNIDIR"
net.zigzak.calcpi.NativePi net.zigzak.calcpi.NativeRNG)
# Remove "empty" header files (they have 13 lines)
wc -l "$JNIDIR"/*.h | grep " 13 " | awk '{print $2}' | xargs rm -f
Classes to extract from
Add path to jar files you depend on
Java types in C/C++
• Java types are mapped to C/C++
types
• Convert Date to long before call
• Pass pointers over as long/
jlong
Java C/C++
long jlong
String jstring
long[] jlongArray
Object jObject
float jfloat
JNIEXPORT jdouble JNICALL Java_net_zigzak_calcpi_NativePi_nativeEstimate
(JNIEnv *, jobject, jlong nativePtr)
{
Pi *pi = reinterpret_cast<Pi *>(nativePtr);
double estimate = pi->estimate();
return estimate;
}
Generated function name
cast to a proper C++ pointer
The pointer
Define as a macro if used often:
#define P(x) reinterpret_cast<Pi *>(x)
Working with arrays
• Copy values from
JVM memory to C/C
++ memory
• Remember to free
C/C++ memory →
avoid memory leaks
jsize arr_len = env->GetArrayLength(columnIndexes);
jlong *arr = env->GetLongArrayElements(columnIndexes, NULL);
// use the elements of arr
env->ReleaseLongArrayElements(columnIndexes, arr, 0);
• Create a new
Java array
• Copy C/C++ array
to Java array
jArray = env->NewByteArray(jlen);
if (jArray)
// Copy data to Byte[]
env->SetByteArrayRegion(jArray, 0, jlen,
reinterpret_cast<const jbyte*>(bufPtr));
free(bufPtr);
return jArray;
Strings as troublemakers
• Java strings are in modified UTF-8
• null character encoded as 0xC0 0x80 (not valid UTF-8)
• Many C/C++ libraries assume plain UTF-8
jchar stack_buf[stack_buf_size];
// adding characters to stack_bf
jchar* out_begin = stack_buf;
if (int_cast_with_overflow_detect(out_curr - out_begin, out_size))
throw runtime_error("String size overflow");
return env->NewString(out_begin, out_size);
jstring s; // typical a JNI function parameter
jchar *c = e->GetStringChars(s, 0);
// use c
env->ReleaseStringChars(s, c);
Create a new Java string
• Copy Java string to C/C++ array
• Remember to deallocate C array
C++ exceptions
• C++ code can throw exceptions
• new can throw bad_alloc,etc.
• If uncaught the app crashes with hard-to-
understand messages in the log
Build fingerprint: 'generic_x86/sdk_x86/generic_x86:4.4.2/KK/999428:eng/test-keys'
Revision: '0'
pid: 1890, tid: 1890, name: t.zigzak.calcpi >>> net.zigzak.calcpi <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
eax 00000000 ebx 00000762 ecx 00000762 edx 00000006
esi 00000762 edi 0000000b
xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007b
eip b7707c96 ebp b776cce0 esp bfa22090 flags 00200203
backtrace:
#00 pc 0003bc96 /system/lib/libc.so (tgkill+22)
#01 pc 00000005 <unknown>
stack:
bfa22050 00000001
bfa22054 b899c6d0 [heap]
bfa22058 00000015
bfa2205c b76d9ef9 /system/lib/libc.so (pthread_mutex_unlock+25)
bfa22060 a73bfd19 /data/app-lib/net.zigzak.calcpi-1/libgnustl_shared.so
bfa22064 b7767fcc /system/lib/libc.so
• Better solution:
• catch and
rethrow as
Java exception
Throwing a Java exception
• You don’t throw an exception
• You set the “exception” state in the
JVM
• Return from C/C++ function
try {
Pi *pi = new Pi(static_cast<long>(iterations));
return reinterpret_cast<jlong>(pi);
}
catch (std::exception& e) {
jclass jExceptionClass =
env->FindClass("java/lang/RuntimeException");
std::ostringstream message;
message << "Allocating native class Pi failed: " << e.what();
env->ThrowNew(jExceptionClass, message.str().c_str());
env->DeleteLocalRef(jExceptionClass);
}
return 0;
! Get a reference to the exception
" Set the “exception” state
# Clean up
followtheinstructrions: hand werpen http://bit.ly/1Bo3gZx
Throwing a Java exception
• You have a proper Java
exception
• Catch it or die (almost
gracefully)
2215-2215/net.zigzak.calcpi E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: net.zigzak.calcpi, PID: 2215
java.lang.RuntimeException: Allocating native class Pi failed: number of iterations must
be larger than 0
at net.zigzak.calcpi.NativePi.nativeCreate(Native Method)
at net.zigzak.calcpi.NativePi.<init>(NativePi.java:13)
at net.zigzak.calcpi.MainActivity.onItemSelected(MainActivity.java:67)
An easy-to-understand message
A Java exception Call stack
Logging
• JNI provides access to the Android log
• __android_log_print is a simple
variadic log function
• Linking with liblog is required
• size_t depends on bit width → cast
to int64_t before logging
vitelone: Deck Log Book http://bit.ly/1AXKZ0j
ndk {
moduleName "calcPi"
cFlags "-std=c++11 -fexceptions"
ldLibs "log"
stl "gnustl_shared" // for exceptions
}
Link flag
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "calcPi", __VA_ARGS__);
Macro to simplify logging
Tracing JNI calls
• It is useful the trace calls
• Define ENTER, ENTER_PTR, and LEAVE macros
• Logging native pointer as jlong often produce
negative numbers - don’t worry
1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeCreate
1955-1955/net.zigzak.calcpi D/calcPi﹕ iterations: 10000
1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeEstimate
-1202665872
1955-1955/net.zigzak.calcpi D/calcPi﹕ estimate = 3.128400e+00
Profiling and debugging
• Use Debug.startMethodTrace() to trace Java
calls
• The Android NDK Profiler project is a port of GNU
Profiler (gprof)1. Supports only ARM and ARMv7.
• Valgrind 3.10 supports Android2
• nVidia has a debugger for the Tegra platform3
adb ps
adb shell am profile start PID FILE
adb shell am profile stop
adb pull FILE .
traceview FILE
1https://code.google.com/p/android-ndk-profiler/
2http://valgrind.org/downloads/current.html
3https://developer.nvidia.com/nvidia-debug-manager-android-ndk
Compiler and linker options
• A few options can reduce the APK size1
• Link Time Optimization (-flto)
• Eliminate unused code (-ffunction-sections
-fdata-sections) and unused ELF symbols (-
fvisibility=hidden)
• Optimize for space (-Os)
• Requires custom Gradle script 😞
1http://realm.io/news/reducing-apk-size-native-libraries/
References
• High Performance Android Apps by Doug Sillars.
O’Reilly Media, 2015 (not yet published).
• Essential JNI by Rob Gordon. Prentice Hall, 1998.
• The Java Native Interface by Sheng Liang.
Addison-Wesley, 1999.
• Android NDK by Sylvian Rataboil. Packt Publishing,
2012.
Questions?
sean dreilinger: question from the audience http://bit.ly/1C1CVB7

Weitere ähnliche Inhalte

Was ist angesagt?

Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012
Anton Arhipov
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
Charles Nutter
 
Mastering Java Bytecode - JAX.de 2012
Mastering Java Bytecode - JAX.de 2012Mastering Java Bytecode - JAX.de 2012
Mastering Java Bytecode - JAX.de 2012
Anton Arhipov
 
Java Bytecode For Discriminating Developers - GeeCON 2011
Java Bytecode For Discriminating Developers - GeeCON 2011Java Bytecode For Discriminating Developers - GeeCON 2011
Java Bytecode For Discriminating Developers - GeeCON 2011
Anton Arhipov
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performance
Duoyi Wu
 

Was ist angesagt? (20)

JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012Mastering java bytecode with ASM - GeeCON 2012
Mastering java bytecode with ASM - GeeCON 2012
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
 
Mastering Java Bytecode - JAX.de 2012
Mastering Java Bytecode - JAX.de 2012Mastering Java Bytecode - JAX.de 2012
Mastering Java Bytecode - JAX.de 2012
 
Java Bytecode For Discriminating Developers - GeeCON 2011
Java Bytecode For Discriminating Developers - GeeCON 2011Java Bytecode For Discriminating Developers - GeeCON 2011
Java Bytecode For Discriminating Developers - GeeCON 2011
 
Using Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard IIUsing Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard II
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Android ndk
Android ndkAndroid ndk
Android ndk
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by example
 
Return of c++
Return of c++Return of c++
Return of c++
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9
 
Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013Beyond JVM - YOW Melbourne 2013
Beyond JVM - YOW Melbourne 2013
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performance
 
SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++
SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++
SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf Linz
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
 
Skiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in DSkiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in D
 

Andere mochten auch (6)

Runtime Innovation - Nextgen Ninja Hacking of the JVM, by Ryan Sciampacone
Runtime Innovation - Nextgen Ninja Hacking of the JVM, by Ryan SciampaconeRuntime Innovation - Nextgen Ninja Hacking of the JVM, by Ryan Sciampacone
Runtime Innovation - Nextgen Ninja Hacking of the JVM, by Ryan Sciampacone
 
Ii 1300-java essentials for android
Ii 1300-java essentials for androidIi 1300-java essentials for android
Ii 1300-java essentials for android
 
Android webinar class_java_review
Android webinar class_java_reviewAndroid webinar class_java_review
Android webinar class_java_review
 
Java or c++
Java or c++Java or c++
Java or c++
 
Intro to Java for C++ Developers
Intro to Java for C++ DevelopersIntro to Java for C++ Developers
Intro to Java for C++ Developers
 
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIsCS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
 

Ähnlich wie Building High Performance Android Applications in Java and C++

MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptx
gopikahari7
 
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
Sang Don Kim
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++
Mohammad Shaker
 
Auto cad 2006_api_overview
Auto cad 2006_api_overviewAuto cad 2006_api_overview
Auto cad 2006_api_overview
scdhruv5
 

Ähnlich wie Building High Performance Android Applications in Java and C++ (20)

C++ in kernel mode
C++ in kernel modeC++ in kernel mode
C++ in kernel mode
 
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
차세대컴파일러, VM의미래: 애플 오픈소스 LLVM
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)Nodejs - A quick tour (v6)
Nodejs - A quick tour (v6)
 
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
 
MattsonTutorialSC14.pdf
MattsonTutorialSC14.pdfMattsonTutorialSC14.pdf
MattsonTutorialSC14.pdf
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptx
 
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
[Td 2015] what is new in visual c++ 2015 and future directions(ulzii luvsanba...
 
Node.js extensions in C++
Node.js extensions in C++Node.js extensions in C++
Node.js extensions in C++
 
Memory Management with Java and C++
Memory Management with Java and C++Memory Management with Java and C++
Memory Management with Java and C++
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 
Auto cad 2006_api_overview
Auto cad 2006_api_overviewAuto cad 2006_api_overview
Auto cad 2006_api_overview
 
Java for the Beginners
Java for the BeginnersJava for the Beginners
Java for the Beginners
 
Node.js - As a networking tool
Node.js - As a networking toolNode.js - As a networking tool
Node.js - As a networking tool
 
OpenCL Heterogeneous Parallel Computing
OpenCL Heterogeneous Parallel ComputingOpenCL Heterogeneous Parallel Computing
OpenCL Heterogeneous Parallel Computing
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 

Mehr von Kenneth Geisshirt

Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012
Kenneth Geisshirt
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integration
Kenneth Geisshirt
 

Mehr von Kenneth Geisshirt (17)

Building parsers in JavaScript
Building parsers in JavaScriptBuilding parsers in JavaScript
Building parsers in JavaScript
 
Open Source in Real Life
Open Source in Real LifeOpen Source in Real Life
Open Source in Real Life
 
Building mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeBuilding mobile apps with Realm for React Native
Building mobile apps with Realm for React Native
 
micro:bit and JavaScript
micro:bit and JavaScriptmicro:bit and JavaScript
micro:bit and JavaScript
 
Tales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleTales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scale
 
Android things
Android thingsAndroid things
Android things
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Is the database a solved problem?
Is the database a solved problem?Is the database a solved problem?
Is the database a solved problem?
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Extending Node.js using C++
Extending Node.js using C++Extending Node.js using C++
Extending Node.js using C++
 
Sociale netværk
Sociale netværkSociale netværk
Sociale netværk
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012
 
Hadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxHadoop - the data scientist's toolbox
Hadoop - the data scientist's toolbox
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integration
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentIntroduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software Development
 
Kendthed og vigtighed
Kendthed og vigtighedKendthed og vigtighed
Kendthed og vigtighed
 

Kürzlich hochgeladen

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Kürzlich hochgeladen (20)

AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 

Building High Performance Android Applications in Java and C++

  • 1. Building High-Performance Android Applications in Java & C++ Kenneth Geisshirt kg@realm.io Realm Inc. @realm http://github.com/Realm/ http://realm.io/ JD Hancock: Reign of The Android. http://bit.ly/1GN8vmg
  • 2. Today’s goal • Android development is not just Java • C and C++ can speed apps up - and reuse old legacy code • Learn a few tricks when working with Java Native Interface Swen-Peter Ekkebus: Goal! http://bit.ly/1x1suYm Avinash Sharma: http://bit.ly/1aRorcH
  • 3. Agenda • About me and Realm • Example: estimating π • Java Native Interface • Building • Memory • Java types, arrays, and strings • Logging and profiling Exploratorium. After Dark: Time http://bit.ly/1aSQxo0
  • 4. About me • Lives in Tårnby, a suburb of Copenhagen • Education • M.Sc. in computer science and chemistry • Ph.D. in soft condensed matter • Commodore 64 was my first home computer • UNIX user, developer, and sysadmin since 1990 • BSD UNIX (Tahoe), Solaris, Linux, Irix, OS X, … • Tech writer and reviewer • Packt Pub, O’Reilly, Linux Magazine, Alt om DATA • Currently working for Realm as developer Leo Reynolds, https://www.flickr.com/photos/lwr/ Shane Doucette, https://www.flickr.com/photos/lwr/
  • 5. About Realm • Founded in 2011 (YC S11) • Funded by Khosla, Scale, … • Distributed work force • Copenhagen: 8 developers • San Francisco: 4 developers + marketing + management • Developers in Århus, Perth, Berlin, Tokyo, and Seoul • New database written from scratch • Cross-platform core in C++ • Full ACID • Fast, low footprint, easy to use • Apache License 2.0 W e are hiring
  • 6. Java Native Interface (JNI) • Use C or C++ in your apps → no JIT needed as always machine instructions • Access to system calls (like mmap()) • Almost no limits on memory usage • OpenGL programming Alan Bates. Good Times http://bit.ly/1BXX7FN
  • 7. JNI disadvantages • C and C++ memory management → easy to crash your app • And debugging across languages is hard • Bionic C library isn’t the GNU C library • Doing a native call is expensive (in time) • Cumbersome to use non-NDK libraries Rocher: That_Sux http://bit.ly/1BdGNhJ
  • 8. Use cases • AndEngine (2D Game Engine) http://www.andengine.org • ImageMagick for Android https://github.com/paulasiimwe/Android-ImageMagick • LevelDB for Android https://github.com/litl/android-leveldb • Support Vector Machine for Android https://github.com/cnbuff410/Libsvm-androidjni
  • 9. Estimating π Estimating π using dart • Throw arrows at random • Nhit/N = A/4 (quarter of a circle) • A = π·r2 (area of a circle) • π = 4·Nhit/N (with r = 1) Bogdan Suditu: Darts. http://bit.ly/18jCExj for i = 1,..,N x = random(0, 1) y = random(0, 1) if (sqrt(x·x+y·y) < 1) Nhit = Nhit +1 π = 4·Nhit/N
  • 10. Example: the app Android app to estimate π • pure Java implementation • pure C++ implementation • mixture of Java (iterations) and C++ (random number generator) • https://github.com/kneth/ AndroidCalcPi
  • 11. Example: the classes Random number generator • Constructor with seed • Method uniform() to return random number between 0.0 and 1.0 π estimator • Constructor with number of iteration • Method estimate() to calculate the value of π Quinn Dombrowski: Pi http://bit.ly/1Kz55cp jeramiah.andrick. My random number generator http://bit.ly/1wbTbP2
  • 12. Organising your files • Place C/C++ files in app/src/main/ jni/src • Add ndk.dir to local.properties • Add an ndk section to your app’s build.gradle ndk { moduleName "calcPi" cFlags "-std=c++11 -fexceptions" stl "gnustl_shared" } add to the android section (currently deprecated)
  • 13. Building and loading your native code • Automatically build for all supported architectures (ARM, ARMv7, ARM64, MIPS, MIPS64, x86, x86-64) • Android only installs the relevant architecture • Load native code early (main activity’s onCreate) System.loadLibrary("calcPi"); The module name (from build.gradle) Thomas Hawk: Loading Zone http://bit.ly/1MoBk9S
  • 14. Calling a C++ function • Use Java’s native keyword in the signature • Implement the function in C++ • Use a long to store the C++ pointer when you creates an object lamont_cranston: call center http://bit.ly/1A4JlK5 native long nativeCreate(long iterations); native double nativeEstimate(long nativePtr); Tell the Java compiler it’s a native function Returns a pointer (a C++ object) Operates on a C++ object
  • 15. Generate header files • .class files contain information about native calls • javah can extract signatures and generate C/C++ header files Paul: Generator Room Door http://bit.ly/1C3SSs7 !/bin/bash # Setting up CLASSDIR="$(pwd)/../app/build/intermediates/classes/debug" JNIDIR="$(pwd)/src" # Generate the headers (cd "$CLASSDIR" && javah -jni -classpath "$CLASSDIR" -d "$JNIDIR" net.zigzak.calcpi.NativePi net.zigzak.calcpi.NativeRNG) # Remove "empty" header files (they have 13 lines) wc -l "$JNIDIR"/*.h | grep " 13 " | awk '{print $2}' | xargs rm -f Classes to extract from Add path to jar files you depend on
  • 16. Java types in C/C++ • Java types are mapped to C/C++ types • Convert Date to long before call • Pass pointers over as long/ jlong Java C/C++ long jlong String jstring long[] jlongArray Object jObject float jfloat JNIEXPORT jdouble JNICALL Java_net_zigzak_calcpi_NativePi_nativeEstimate (JNIEnv *, jobject, jlong nativePtr) { Pi *pi = reinterpret_cast<Pi *>(nativePtr); double estimate = pi->estimate(); return estimate; } Generated function name cast to a proper C++ pointer The pointer Define as a macro if used often: #define P(x) reinterpret_cast<Pi *>(x)
  • 17. Working with arrays • Copy values from JVM memory to C/C ++ memory • Remember to free C/C++ memory → avoid memory leaks jsize arr_len = env->GetArrayLength(columnIndexes); jlong *arr = env->GetLongArrayElements(columnIndexes, NULL); // use the elements of arr env->ReleaseLongArrayElements(columnIndexes, arr, 0); • Create a new Java array • Copy C/C++ array to Java array jArray = env->NewByteArray(jlen); if (jArray) // Copy data to Byte[] env->SetByteArrayRegion(jArray, 0, jlen, reinterpret_cast<const jbyte*>(bufPtr)); free(bufPtr); return jArray;
  • 18. Strings as troublemakers • Java strings are in modified UTF-8 • null character encoded as 0xC0 0x80 (not valid UTF-8) • Many C/C++ libraries assume plain UTF-8 jchar stack_buf[stack_buf_size]; // adding characters to stack_bf jchar* out_begin = stack_buf; if (int_cast_with_overflow_detect(out_curr - out_begin, out_size)) throw runtime_error("String size overflow"); return env->NewString(out_begin, out_size); jstring s; // typical a JNI function parameter jchar *c = e->GetStringChars(s, 0); // use c env->ReleaseStringChars(s, c); Create a new Java string • Copy Java string to C/C++ array • Remember to deallocate C array
  • 19. C++ exceptions • C++ code can throw exceptions • new can throw bad_alloc,etc. • If uncaught the app crashes with hard-to- understand messages in the log Build fingerprint: 'generic_x86/sdk_x86/generic_x86:4.4.2/KK/999428:eng/test-keys' Revision: '0' pid: 1890, tid: 1890, name: t.zigzak.calcpi >>> net.zigzak.calcpi <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- eax 00000000 ebx 00000762 ecx 00000762 edx 00000006 esi 00000762 edi 0000000b xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007b eip b7707c96 ebp b776cce0 esp bfa22090 flags 00200203 backtrace: #00 pc 0003bc96 /system/lib/libc.so (tgkill+22) #01 pc 00000005 <unknown> stack: bfa22050 00000001 bfa22054 b899c6d0 [heap] bfa22058 00000015 bfa2205c b76d9ef9 /system/lib/libc.so (pthread_mutex_unlock+25) bfa22060 a73bfd19 /data/app-lib/net.zigzak.calcpi-1/libgnustl_shared.so bfa22064 b7767fcc /system/lib/libc.so • Better solution: • catch and rethrow as Java exception
  • 20. Throwing a Java exception • You don’t throw an exception • You set the “exception” state in the JVM • Return from C/C++ function try { Pi *pi = new Pi(static_cast<long>(iterations)); return reinterpret_cast<jlong>(pi); } catch (std::exception& e) { jclass jExceptionClass = env->FindClass("java/lang/RuntimeException"); std::ostringstream message; message << "Allocating native class Pi failed: " << e.what(); env->ThrowNew(jExceptionClass, message.str().c_str()); env->DeleteLocalRef(jExceptionClass); } return 0; ! Get a reference to the exception " Set the “exception” state # Clean up followtheinstructrions: hand werpen http://bit.ly/1Bo3gZx
  • 21. Throwing a Java exception • You have a proper Java exception • Catch it or die (almost gracefully) 2215-2215/net.zigzak.calcpi E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: net.zigzak.calcpi, PID: 2215 java.lang.RuntimeException: Allocating native class Pi failed: number of iterations must be larger than 0 at net.zigzak.calcpi.NativePi.nativeCreate(Native Method) at net.zigzak.calcpi.NativePi.<init>(NativePi.java:13) at net.zigzak.calcpi.MainActivity.onItemSelected(MainActivity.java:67) An easy-to-understand message A Java exception Call stack
  • 22. Logging • JNI provides access to the Android log • __android_log_print is a simple variadic log function • Linking with liblog is required • size_t depends on bit width → cast to int64_t before logging vitelone: Deck Log Book http://bit.ly/1AXKZ0j ndk { moduleName "calcPi" cFlags "-std=c++11 -fexceptions" ldLibs "log" stl "gnustl_shared" // for exceptions } Link flag #define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "calcPi", __VA_ARGS__); Macro to simplify logging
  • 23. Tracing JNI calls • It is useful the trace calls • Define ENTER, ENTER_PTR, and LEAVE macros • Logging native pointer as jlong often produce negative numbers - don’t worry 1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeCreate 1955-1955/net.zigzak.calcpi D/calcPi﹕ iterations: 10000 1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeEstimate -1202665872 1955-1955/net.zigzak.calcpi D/calcPi﹕ estimate = 3.128400e+00
  • 24. Profiling and debugging • Use Debug.startMethodTrace() to trace Java calls • The Android NDK Profiler project is a port of GNU Profiler (gprof)1. Supports only ARM and ARMv7. • Valgrind 3.10 supports Android2 • nVidia has a debugger for the Tegra platform3 adb ps adb shell am profile start PID FILE adb shell am profile stop adb pull FILE . traceview FILE 1https://code.google.com/p/android-ndk-profiler/ 2http://valgrind.org/downloads/current.html 3https://developer.nvidia.com/nvidia-debug-manager-android-ndk
  • 25. Compiler and linker options • A few options can reduce the APK size1 • Link Time Optimization (-flto) • Eliminate unused code (-ffunction-sections -fdata-sections) and unused ELF symbols (- fvisibility=hidden) • Optimize for space (-Os) • Requires custom Gradle script 😞 1http://realm.io/news/reducing-apk-size-native-libraries/
  • 26. References • High Performance Android Apps by Doug Sillars. O’Reilly Media, 2015 (not yet published). • Essential JNI by Rob Gordon. Prentice Hall, 1998. • The Java Native Interface by Sheng Liang. Addison-Wesley, 1999. • Android NDK by Sylvian Rataboil. Packt Publishing, 2012.
  • 27. Questions? sean dreilinger: question from the audience http://bit.ly/1C1CVB7