<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hi,<br>
I'm not 100% this discussion is a good fit for this mailing list.
The issue you are reporting seems to have nothing to do with the
FFM API, or SymbolLookup.</p>
<p>Honestly, from the kind of numbers you get, I tend to agree with
Sebastian when he said this:</p>
<p>
<blockquote type="cite">
<div dir="ltr">If you think that copying it is the culprit, it
may be some other OS security feature, since it is the first
time for the OS to open the binary from a new location…?</div>
</blockquote>
<br>
E.g there seems to be something kicking in when that temporary
folder is touched, anti-virus, or something else (this is a shared
lib you are moving around, so it wouldn't be surprising if the OS
looked at that operation suspiciously).</p>
<p>For instance:</p>
<p><a class="moz-txt-link-freetext" href="https://support.apple.com/en-ie/HT202491">https://support.apple.com/en-ie/HT202491</a></p>
<p>Have you tried setting your OS to trust applications from any
source? (temporarily of course). Does that make any difference?</p>
<p>I think it would be good to capture the situation you are facing
in a bug report - but before we do that, I guess it would be great
if you could setup a repo somewhere with some reproducer that
other people can just run (e.g. something with maven or gradle?).
So that we can have a better ideas of what might be the culprit
and/or which OS might be affected.</p>
<p>Note that having a dependency on Netty might make things more
confusing - when you access a static method on KQueue, you are
going to run static initializers (I don't know off-hand how many),
but it is not unusual for big frameworks to have a biggie startup
time - since in Java classes are loaded and initialized on demand,
you only see that cost when you call the KQueue method - but you
are not just measuring how long does it take for that method to
complete, you are also measuring the time the JVM takes to load
_all_ the classes that might be required (and they might be more
then you think) as well as running static initializers on some of
them (which might pull in more classes, etc.).</p>
<p>Try to run with the JVM `-verbose` option, which prints which
classes are loaded and when, so that you can get an idea of how
much stuff actually happens when you call that KQueue method.</p>
<p>Cheers<br>
Maurizio<br>
</p>
<div class="moz-cite-prefix">On 27/05/2023 18:34, 刘希晨 wrote:<br>
</div>
<blockquote type="cite" cite="mid:CABUmArT_OU-Hm8w4hCpFgF9tGK_rKuoW2Tn283MbsUCJU_MPog@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">Today I did some more tests about the scenario,
and what surprised me is that this problem has a wide
influence.
<div><br>
</div>
<div>I am not an expert in C or C++, and I am not familiar
with the underlying JVM source codes, I could only judge
from the results and let you guys find out what's really
wrong.</div>
<div><br>
</div>
<div>This copy then loadlibrary mechanism has been used by a
lot of famous open-source projects, such as Netty or
RocksDB, in fact I learned from them when I was developing
my own framework.</div>
<div>So I tested a really really simple example to prove my
idea.</div>
<div><br>
</div>
<div>
<div style="background-color:rgb(30,31,34);color:rgb(188,190,196)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(207,142,109)">package </span>com.example.demo;
<span style="color:rgb(207,142,109)">import </span>io.netty.channel.kqueue.KQueue;
<span style="color:rgb(207,142,109)">public class </span>NativeTest {
<span style="color:rgb(207,142,109)">public static void </span><span style="color:rgb(86,168,245)">main</span>(String[] args) {
<span style="color:rgb(207,142,109)">long </span>l = System.<span style="font-style:italic">currentTimeMillis</span>();
KQueue.<span style="font-style:italic">isAvailable</span>();
System.<span style="color:rgb(199,125,187);font-style:italic">out</span>.println(System.<span style="font-style:italic">currentTimeMillis</span>() - l);
}
}</pre>
</div>
</div>
</div>
<div><br>
</div>
<div>The Kqueue static block will load the underlying Kqueue
dylib library into the process, and this single line cost
900ms on my M1-pro Macbook, while starting a tcp server cost
about 1000ms, which is to say that most of the time was
consumed by this mechanism.</div>
<div><br>
</div>
<div>Just try the code above, I don't know why this is
happening, and hope you experts could prove me wrong. cheers!</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">Sebastian Stenzel <<a href="mailto:sebastian.stenzel@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">sebastian.stenzel@gmail.com</a>>
于2023年5月27日周六 13:54写道:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="auto">
<div dir="ltr">Have you tried copying and dlopen'ing the
.dylib from a C program?</div>
<div dir="ltr">If you think that copying it is the
culprit, it may be some other OS security feature, since
it is the first time for the OS to open the binary from
a new location…?</div>
<br>
<div dir="ltr">
<blockquote type="cite">Am 27.05.2023 um 04:18 schrieb
刘希晨 <<a href="mailto:benrush0705@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">benrush0705@gmail.com</a>>:<br>
<br>
</blockquote>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">The temp folder is not an influence
factor, it will happen in any folder that calling
System.load() or SymbolLookup.librarylookup() on a
new copied dynamic library, as long as the target
dynamic library was just created in filesystem by
copy() or other mechanism. Calling for the first
time is even worse, might take a second to do the
job, since then it becomes 300ms per call. I also
tested changing the file size of the .dylib, which
seems to have no effect on the time consumption.</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">刘希晨 <<a href="mailto:benrush0705@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">benrush0705@gmail.com</a>>
于2023年5月27日周六 08:16写道:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">Sorry guys, fall asleep last night,
cause it's late in my country.
<div><br>
</div>
<div>I have run some more tests, and now I am
100% percent sure that the problem is not
about System.load() or
SymbolLookup.librarylookup() and I am pretty
sure it should be reproducible.</div>
<div><br>
</div>
<div>here is the minimal version of the
reproducible code:</div>
<div><br>
</div>
<div>```</div>
<div>
<div style="background-color:rgb(30,31,34);color:rgb(188,190,196)">
<pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(207,142,109)">private static final </span>String <span style="color:rgb(199,125,187);font-style:italic">s </span>= <span style="color:rgb(106,171,115)">"/Users/liuxichen/workspace/demo/src/main/resources/lib/libcrypto.3.dylib"</span>;
<span style="color:rgb(207,142,109)">public static void </span><span style="color:rgb(86,168,245)">main</span>(String[] args) <span style="color:rgb(207,142,109)">throws </span>IOException {
<span style="color:rgb(207,142,109)">long </span>start = System.<span style="font-style:italic">currentTimeMillis</span>();
FileInputStream fileInputStream = <span style="color:rgb(207,142,109)">new </span>FileInputStream(<span style="color:rgb(199,125,187);font-style:italic">s</span>);
File f = File.<span style="font-style:italic">createTempFile</span>(<span style="color:rgb(106,171,115)">"test"</span>, <span style="color:rgb(106,171,115)">".dylib"</span>);
Path p = f.toPath();
Files.<span style="font-style:italic">copy</span>(fileInputStream, p, StandardCopyOption.<span style="color:rgb(199,125,187);font-style:italic">REPLACE_EXISTING</span>);
f.deleteOnExit();
System.<span style="color:rgb(199,125,187);font-style:italic">out</span>.println(<span style="color:rgb(106,171,115)">"File operation cost : " </span>+ (System.<span style="font-style:italic">currentTimeMillis</span>() - start));
SymbolLookup symbolLookup = SymbolLookup.<span style="font-style:italic">libraryLookup</span>(p, SegmentScope.<span style="font-style:italic">global</span>());
System.<span style="color:rgb(199,125,187);font-style:italic">out</span>.println(<span style="color:rgb(106,171,115)">"all cost : " </span>+ (System.<span style="font-style:italic">currentTimeMillis</span>() - start));
fileInputStream.close();
}</pre>
</div>
</div>
<div>```</div>
<div><br>
</div>
<div>here is my test results :</div>
<div>1. Just running System.load() or
SymbolLookup.librarylookup() will have no
problem and that should cost just about 3ms,
no matter it's in the normal folder or in the
tmp folder.</div>
<div>2. If using mechanism in the above codes,
which is directly call
SymbolLookup.librarylookup() right after
copying file to tmp folder, the operation is
quite slow, it takes about 300ms each time on
my M1-pro chips</div>
<div>3. The performance drop using above code is
not that obvious on Windows or Linux, cost
about 20ms</div>
<div><br>
</div>
<div>I think my OpenSSL library is right in
arm architecture, since I install it using
homebrew:</div>
<div>❯ openssl version -a<br>
OpenSSL 3.1.0 14 Mar 2023 (Library: OpenSSL
3.1.0 14 Mar 2023)<br>
built on: Tue Mar 14 12:59:07 2023 UTC<br>
platform: darwin64-arm64-cc<br>
options: bn(64,64)<br>
compiler: clang -fPIC -arch arm64 -O3 -Wall
-DL_ENDIAN -DOPENSSL_PIC -D_REENTRANT
-DOPENSSL_BUILDING_OPENSSL -DNDEBUG<br>
OPENSSLDIR: "/opt/homebrew/etc/openssl@3"<br>
ENGINESDIR:
<a class="moz-txt-link-rfc2396E" href="mailto:/opt/homebrew/Cellar/openssl@3/3.1.0/lib/engines-3">"/opt/homebrew/Cellar/openssl@3/3.1.0/lib/engines-3"</a><br>
MODULESDIR:
<a class="moz-txt-link-rfc2396E" href="mailto:/opt/homebrew/Cellar/openssl@3/3.1.0/lib/ossl-modules">"/opt/homebrew/Cellar/openssl@3/3.1.0/lib/ossl-modules"</a><br>
Seeding source: os-specific<br>
CPUINFO: OPENSSL_armcap=0x187d<br>
</div>
<div><br>
</div>
<div><br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">Sebastian
Stenzel <<a href="mailto:sebastian.stenzel@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">sebastian.stenzel@gmail.com</a>>
于2023年5月27日周六 02:22写道:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">Is it
reproducible? Maybe your openssl .dylib is
x86_64 and Rosetta kicked in on first use?<br>
<br>
> Am 26.05.2023 um 18:21 schrieb Maurizio
Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>:<br>
> <br>
> <br>
>> On 26/05/2023 16:51, 刘希晨 wrote:<br>
>> I noticed a weird problem about
SymbolLookup.libraryLookup() with
SegmentScope.global when I was testing on my
M1-pro macbook using JDK20, the method took
about 700ms to finish when loading OpenSSL's
dynamic library, this result is quite slow. I
tested on Windows and Linux(using WSL on
Windows) with older hardware (AMD Ryzen 3700x)
and it takes around 100ms. Please run some
tests about this situation and correct me if I
am wrong. Thanks for your help!<br>
> Hi,<br>
> <br>
> this seems very odd, we will look into
it.<br>
> <br>
> Note that SymbolLookup::libraryLookup
just ends up straight into a dlopen call.
There are not many strings attached, really.
700ms (but even 100ms) seems quite a lot to
me.<br>
> <br>
> Can you also try with System::loadLibrary
- is it faster that way (I very much doubt it,
since the underlying code is the same?)<br>
> <br>
> Cheers<br>
> Maurizio<br>
> <br>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</body>
</html>