Cortiveo i GEngine - prirucnik

↑ Nazad

Tracer se kači preko JDWP-a (isti protokol kao debager). Aplikacija se ne menja i ostaje na svom JVM-u. Radi na portabilnom JDK 17, a cilj može biti Java 8.

cortiveo trace --app gjava.,db.,milos. --args 3 --tail 8000 --port 5005
cortiveo trace --app io.cortiveo. -- tools\jdk8\bin\java.exe -jar app.jar

Prvi oblik se kači na JVM koji već sluša (server=y) — ne mora se ponovo prolaziti prijava. Drugi sam pokreće aplikaciju sa -agentlib:jdwp.

Zlatno pravilo: JDI se plaća po događaju, ne po dubini

Ne postoji „javi mi samo prvi ulaz u ovu biblioteku". Postoje dva mehanizma i razlika je ogromna:

mehanizamkada koštaza šta
MethodEntryRequestna svakom ulazu u bilo koju metodu iz filtriranog skupatvoj kod, gde hoćeš sve
BreakpointRequestsamo kad se pogodigranica ka tuđem kodu, SQL, trigeri

Zato tracer: tvoje pakete prati MethodEntry, a tuđi kod ne prati uopšte — granicu imenuješ.

Opcije koje vrede

opcijašta radi
--app db.,milos.šta se smatra „mojim kodom" (trigeri, lanci pozivalaca)
--watch db.,milos.,-db.tehnobiro.generator3.DataHPrintBaseUtilitiesza čim se stvarno prate pozivi; član sa - se izuzima i ne plaća
--args 3vrednosti argumenata: Db.update("UPDATE invoice SET ..."...(51))
--call com.google.zxing.qrcode.QRCodeWriter.encodegranica ka biblioteci: koja metoda i sa čim, bez ulaska u nju
--trigger actionPerformed,menuCallšta otvara stablo (klik, ali i poziv bez GUI-ja)
--tail 8000još toliko ms posle klika hvata SQL — ekran često puni podatke iz invokeLater
--skip prefiksklasa sa celim podstablom se ne ispisuje (ali se plaća)
--depth N, --max Nkoliko duboko i koliko redova
--progress 2000red o napretku svake 2 s — bez njega tracer ćuti dok radi
--scan„apsolutno sve": i tuđi kod u stablo. Skupo, ali vidi sve

Obrazac poklapanja: sa tačkom na kraju = paket (db.), bez tačke = tačna klasa i njene unutrašnje (gjava.data.GDataSource ne hvata GDataSourceLevel20).

Red o napretku — protiv tišine

... klik #2 12 s, 8432 poziva (+680), 2 sql, d11 GDataSource2d.recreateData
... klik #2 14 s, 8432 poziva, stoji (tudji kod ili baza), 2 sql, d11 GDataSource2d.recreateData

Čita se: broj poziva raste → radi; stoji → čeka bazu ili biblioteku; red koji se ponavlja sa (xN) → petlja. Bez ovoga tracer ćuti upravo u najdužim delovima (tuđi kod, ispod --depth, posle --max), pa se ne zna da li se čeka uzalud.

Merenja na pravoj aplikaciji (2026-09-22/23)

štabrojkazaključak
klik na stavku menija1017 poziva, 0 SQL, ~0,9 sposao ide van klika, kroz invokeLater
isti klik sa --args 31,6 svrednosti argumenata ≈ 1,2 ms po ispisanom redu
menuCall (posao ekrana)58 104 poziva, 7 SQL, 94 sod toga 67,7 s u jednom SELECT-u
klik na dugme u ekranu17 059 poziva, 3 SQL, 18 s
klik na štampu (--scan-oliki profil)175 012 poziva posle 47 minuta, bez krajaamplifikacija metapodataka
raspodela redova stabla7627 gjava. : 64 db.99% cene je framework, 1% poslovna logika

Dva nalaza koja su promenila alat

  1. 67 sekundi nije bila baza. Tabela ima 4 reda. Tracer je imao MethodEntry nad svim ne-JDK klasama, pa se plaćao svaki ulaz u MySQL drajver dok se čitao rezultat. Rešenje: SQL se hvata breakpoint-om na JDBC metodama (nađenim od java.sql.Connection/Statement kroz podinterfejse do implementacija) — drajver radi punom brzinom.
  2. 175 000 poziva u štampi bili su GDataSourceLevel20.getColumn, GDataSource2d.getRowCount, columnExists — po koloni × po redu × po elementu štampe. To je cena arhitekture, ne greška tracera; tracer je samo prvi put izmerio.

Kako se prati štampa (a da se ne čeka do sutra)

--app gjava.,db.,milos.
--watch db.,milos.,gjava.data.GDataSource,-db.tehnobiro.generator3.DataHPrintBaseUtilities
--call com.google.zxing.MultiFormatWriter.encode,com.google.zxing.qrcode.QRCodeWriter.encode
--args 3 --trigger actionPerformed,menuCall --tail 8000 --stack 8 --progress 2000

Prevod: prati moju poslovnu logiku i ulaz u ekran, ne gradnju svakog pasusa i slike, a od biblioteka mi javi samo poziv QR koderu i njegove parametre.

Put bez GUI-ja (cilj projekta)

Aplikacija već ima ulaz bez ekrana: gjava.interfaces.GMenuCallable

GError menuCall(GAppFrame pCallingFrame, String pParameters);

Isti menuCall se vidi i u tragu klika (GDataSource.menuCall, GDataSource.java:308), pa je svaki posao koji se može odraditi klikom moguće odraditi i pozivom. Trag jednog klika sa --args pokazuje tačan poziv:

GDataSource.menuCall(GMainFrame@3389, "")          GDataSource.java:308
  Definition.edit(GMainFrame@3389, Object[0])      Definition.java:77
    GDataSource.edit(GMainFrame@3389, Object[0])   GDataSource.java:328

To je recept: pokaži klikom, izvrši pozivom.

Ostalo u alatu

Popravke u aplikaciji koje su nastale iz merenja

Izvor: 05-cortiveo-tracer.md