Skip to content

Commit 4d803c6

Browse files
committed
draft
1 parent 6ceb0b6 commit 4d803c6

File tree

15 files changed

+658
-56
lines changed

15 files changed

+658
-56
lines changed

binary/xstream-1.5.0-bsl.jar

671 KB
Binary file not shown.

build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ dependencies {
5252

5353
implementation("org.apache.commons", "commons-collections4", "4.4")
5454

55-
implementation("com.thoughtworks.xstream", "xstream", "1.4.21")
55+
// implementation("com.thoughtworks.xstream", "xstream", "1.4.21")
56+
compileOnly(files("binary/xstream-1.5.0-bsl.jar"))
5657

5758
// логирование
5859
implementation("org.slf4j", "slf4j-api", "2.1.0-alpha1")

log.log

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
2+
3+
> Configure project :
4+
matching ref: BRANCH - feature/jol
5+
ref configuration: BRANCH - pattern: .+
6+
version: ${ref}-${commit.short}${dirty}
7+
describeTagFirstParent: false
8+
9+
project version: feature-jol-6ceb0b6-DIRTY
10+
11+
> Task :generateEffectiveLombokConfig UP-TO-DATE
12+
> Task :compileJava UP-TO-DATE
13+
> Task :processResources NO-SOURCE
14+
> Task :classes UP-TO-DATE
15+
> Task :generateTestEffectiveLombokConfig UP-TO-DATE
16+
> Task :compileTestJava UP-TO-DATE
17+
> Task :processTestResources UP-TO-DATE
18+
> Task :testClasses UP-TO-DATE
19+
> Task :test
20+
> Task :test FAILED
21+
22+
[Incubating] Problems report is available at: file:///home/vmaksimov@dellin.local/reps/1c-syntax/mdclasses/build/reports/problems/problems-report.html
23+
24+
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
25+
26+
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
27+
28+
For more on this, please refer to https://docs.gradle.org/8.14.3/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
29+
6 actionable tasks: 1 executed, 5 up-to-date

src/main/java/com/github/_1c_syntax/bsl/mdclasses/MDClasses.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ private List<Path> findFiles(Path sourcePath, Pattern pattern) {
276276

277277
var parentName = path.getParent().getFileName().toString();
278278
var parentParentName = "";
279-
if (path.getParent().getParent() != null) {
279+
if (path.getParent().getParent() != null && path.getParent().getParent().getFileName() != null) {
280280
parentParentName = path.getParent().getParent().getFileName().toString();
281281
}
282282

src/main/java/com/github/_1c_syntax/bsl/reader/common/xstream/ExtendXStream.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public ExtendXStream(MDReader reader, QNameMap qNameMap, ClassLoaderReference cl
116116
* @return Прочитанный объект
117117
*/
118118
@Override
119+
@SuppressWarnings("unchecked")
119120
public Object fromXML(File file) {
120121
Object result = null;
121122
if (file.exists()) {

src/test/java/com/github/_1c_syntax/bsl/test_utils/MDTestUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ public ExternalSource readExternalSourceWithSimpleTest(ArgumentsAccessor argumen
244244
private void objectEqualJson(Object obj, Path fixturePath) {
245245
var fixture = getFixture(fixturePath);
246246
var current = createJson(obj);
247-
247+
// Files.writeString(fixturePath, current, StandardCharsets.UTF_8);
248248
Assertions.assertThat(fixRusYi(current), true).isEqual(fixRusYi(fixture));
249249
}
250250

src/test/java/com/github/_1c_syntax/jol/MemoryAnalyze.java

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,151 @@
2121
*/
2222
package com.github._1c_syntax.jol;
2323

24+
import com.github._1c_syntax.bsl.mdclasses.CF;
25+
import com.github._1c_syntax.bsl.mdclasses.MDClasses;
26+
import com.github._1c_syntax.bsl.mdo.Form;
27+
import com.github._1c_syntax.bsl.mdo.Role;
28+
import com.github._1c_syntax.bsl.mdo.storage.FormData;
29+
import com.github._1c_syntax.bsl.mdo.storage.RoleData;
30+
import com.github._1c_syntax.jol.memory.AnalysisResult;
2431
import com.github._1c_syntax.jol.memory.MemoryAnalyzer;
32+
import lombok.extern.slf4j.Slf4j;
33+
import org.openjdk.jol.vm.VM;
2534

35+
import java.nio.file.Path;
36+
import java.util.ArrayList;
37+
import java.util.Collection;
38+
import java.util.List;
39+
import java.util.Map;
40+
import java.util.stream.Collectors;
41+
42+
@Slf4j
2643
public class MemoryAnalyze {
44+
45+
private static final Path CF = Path.of("/home/vmaksimov@dellin.local/reps/onec/erp/src");
46+
2747
public static void main(String[] args) {
48+
LOGGER.info("=== MEMORY ANALYSIS CLASSES REPORT ===");
49+
LOGGER.info("JVM details: {}", VM.current().details());
50+
LOGGER.info("");
51+
52+
if (CF.toFile().exists()) {
53+
analyzeClassesByCF();
54+
} else {
55+
analyzeClasses();
56+
}
57+
}
58+
59+
private static void analyzeClasses() {
60+
LOGGER.info("Without real data");
61+
LOGGER.info("");
62+
2863
var results = MemoryAnalyzer.analyzeClasses(
2964
"com.github._1c_syntax.bsl.mdo",
3065
"com.github._1c_syntax.bsl.mdclasses"
3166
);
3267
MemoryAnalyzer.printAnalysisReport(results);
3368
}
69+
70+
private static void analyzeClassesByCF() {
71+
LOGGER.info("For {}", CF);
72+
LOGGER.info("");
73+
74+
var mdc = (CF) MDClasses.createSolution(CF);
75+
mdc.getPlainChildren();
76+
mdc.getModuleTypes();
77+
mdc.getAllModules();
78+
mdc.getChildrenByMdoRef();
79+
mdc.getModulesByURI();
80+
mdc.getModulesByObject();
81+
82+
83+
// дочерние
84+
var map = mdc.getPlainChildren().stream()
85+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()))
86+
;
87+
analyzeAndPrint(map);
88+
89+
// части формы
90+
var form = mdc.getPlainChildren().stream()
91+
.filter(Form.class::isInstance)
92+
.map(Form.class::cast)
93+
.map(Form::getData)
94+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
95+
analyzeAndPrint(form);
96+
97+
var formElements = mdc.getPlainChildren().stream()
98+
.filter(Form.class::isInstance)
99+
.map(Form.class::cast)
100+
.map(Form::getData)
101+
.map(FormData::getPlainItems)
102+
.flatMap(Collection::stream)
103+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
104+
analyzeAndPrint(formElements);
105+
106+
var formAttributes = mdc.getPlainChildren().stream()
107+
.filter(Form.class::isInstance)
108+
.map(Form.class::cast)
109+
.map(Form::getData)
110+
.map(FormData::getAttributes)
111+
.flatMap(Collection::stream)
112+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
113+
analyzeAndPrint(formAttributes);
114+
115+
var formHandles = mdc.getPlainChildren().stream()
116+
.filter(Form.class::isInstance)
117+
.map(Form.class::cast)
118+
.map(Form::getData)
119+
.map(FormData::getHandlers)
120+
.flatMap(Collection::stream)
121+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
122+
analyzeAndPrint(formHandles);
123+
124+
// роли
125+
var role = mdc.getPlainChildren().stream()
126+
.filter(Role.class::isInstance)
127+
.map(Role.class::cast)
128+
.map(Role::getData)
129+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
130+
analyzeAndPrint(role);
131+
132+
var roleRight = mdc.getPlainChildren().stream()
133+
.filter(Role.class::isInstance)
134+
.map(Role.class::cast)
135+
.map(Role::getData)
136+
.map(RoleData::objectRights)
137+
.flatMap(Collection::stream)
138+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
139+
analyzeAndPrint(roleRight);
140+
141+
var roleRights = mdc.getPlainChildren().stream()
142+
.filter(Role.class::isInstance)
143+
.map(Role.class::cast)
144+
.map(Role::getData)
145+
.map(RoleData::objectRights)
146+
.flatMap(Collection::stream)
147+
.map(RoleData.ObjectRight::rights)
148+
.flatMap(Collection::stream)
149+
.collect(Collectors.groupingBy(Object::getClass, Collectors.toList()));
150+
analyzeAndPrint(roleRights);
151+
}
152+
153+
private static <T> void analyzeAndPrint(Map<? extends Class<?>, List<T>> map) {
154+
map.forEach((aClass, elements) -> {
155+
List<AnalysisResult> results = new ArrayList<>();
156+
// AtomicInteger count = new AtomicInteger();
157+
elements.forEach(md -> {
158+
results.add(MemoryAnalyzer.analyzeClass(md));
159+
// count.getAndIncrement();
160+
});
161+
162+
// LOGGER.info("Count {}", count);
163+
// var sorted = results.stream()
164+
// .sorted(Comparator.comparing(AnalysisResult::getTotalSize).reversed())
165+
//// .limit(1)
166+
// .toList();
167+
MemoryAnalyzer.printAnalysisReport(results);
168+
}
169+
);
170+
}
34171
}

src/test/java/com/github/_1c_syntax/jol/memory/MemoryAnalyzer.java

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import lombok.extern.slf4j.Slf4j;
3030
import org.openjdk.jol.info.ClassLayout;
3131
import org.openjdk.jol.info.GraphLayout;
32-
import org.openjdk.jol.vm.VM;
3332

3433
import java.lang.reflect.Modifier;
3534
import java.util.ArrayList;
@@ -55,45 +54,49 @@ public List<AnalysisResult> analyzeClasses(String... basePackages) {
5554
.map(MemoryAnalyzer::analyzeClass)
5655
.filter(Objects::nonNull)
5756
.sorted(Comparator.comparing(AnalysisResult::getWastedBytes).reversed())
57+
.limit(10)
5858
.toList();
5959
}
6060

6161
public void printAnalysisReport(List<AnalysisResult> results) {
62-
LOGGER.info("=== MEMORY ANALYSIS REPORT ===");
63-
LOGGER.info("JVM details: {}", VM.current().details());
64-
LOGGER.info("");
65-
66-
for (var result : results) {
67-
if(result.getAlignmentEfficiency() == 100) {
68-
continue;
69-
}
70-
LOGGER.info("Class: {}", result.getClassName());
71-
LOGGER.info("Instance size: {} bytes", result.getInstanceSize());
72-
LOGGER.info("Total size: {} bytes", result.getTotalSize());
73-
LOGGER.info("Wasted bytes: {} bytes", result.getWastedBytes());
74-
LOGGER.info("Alignment efficiency: {}", String.format("%.2f", result.getAlignmentEfficiency()) + "%");
75-
76-
if (!result.getAlignmentIssues().isEmpty()) {
77-
LOGGER.info("Alignment issues:");
78-
for (FieldAlignmentIssue issue : result.getAlignmentIssues()) {
79-
LOGGER.info(" - {}: {} bytes", issue.description(), issue.paddingSize());
80-
}
81-
}
82-
83-
if (!result.getOptimizationSuggestions().isEmpty()) {
84-
LOGGER.info("Optimization suggestions:");
85-
for (String suggestion : result.getOptimizationSuggestions()) {
86-
LOGGER.info(" - {}", suggestion);
87-
}
88-
}
89-
90-
LOGGER.info("Field sizes:");
91-
result.getFieldSizes().forEach(
92-
(field, size) -> LOGGER.info(" {}: {} bytes", field, size)
93-
);
94-
95-
LOGGER.info("---");
62+
if (!results.isEmpty()) {
63+
var rec = results.get(0);
64+
LOGGER.info("Class: {}", rec.getClassName());
65+
LOGGER.info("Count: {}", results.size());
66+
LOGGER.info("Instance size: {} bytes", rec.getInstanceSize());
67+
LOGGER.info("Total size: {} bytes", results.stream().mapToLong(AnalysisResult::getTotalSize).sum());
68+
LOGGER.info("Wasted bytes: {} bytes", rec.getWastedBytes());
69+
LOGGER.info("Alignment efficiency: {}", String.format("%.2f", rec.getAlignmentEfficiency()) + "%");
9670
}
71+
//
72+
// for (var result : results) {
73+
// LOGGER.info("Class: {}", result.getClassName());
74+
// LOGGER.info("Instance size: {} bytes", result.getInstanceSize());
75+
// LOGGER.info("Total size: {} bytes", result.getTotalSize());
76+
// LOGGER.info("Wasted bytes: {} bytes", result.getWastedBytes());
77+
// LOGGER.info("Alignment efficiency: {}", String.format("%.2f", result.getAlignmentEfficiency()) + "%");
78+
//
79+
//// if (!result.getAlignmentIssues().isEmpty()) {
80+
//// LOGGER.info("Alignment issues:");
81+
//// for (FieldAlignmentIssue issue : result.getAlignmentIssues()) {
82+
//// LOGGER.info(" - {}: {} bytes", issue.description(), issue.paddingSize());
83+
//// }
84+
//// }
85+
//
86+
//// if (!result.getOptimizationSuggestions().isEmpty()) {
87+
//// LOGGER.info("Optimization suggestions:");
88+
//// for (String suggestion : result.getOptimizationSuggestions()) {
89+
//// LOGGER.info(" - {}", suggestion);
90+
//// }
91+
//// }
92+
//
93+
//// LOGGER.info("Field sizes:");
94+
//// result.getFieldSizes().forEach(
95+
//// (field, size) -> LOGGER.info(" {}: {} bytes", field, size)
96+
//// );
97+
//
98+
// LOGGER.info("---");
99+
// }
97100
}
98101

99102
/**
@@ -209,28 +212,11 @@ private boolean isDTOLikeClass(ClassInfo classInfo) {
209212
private Map<String, Long> calculateFieldSizes(ClassLayout classLayout) {
210213
Map<String, Long> fieldSizes = new LinkedHashMap<>();
211214
classLayout.fields().forEach(field -> {
212-
var fieldSize = getFieldSize(field.typeClass().getClass());
213-
fieldSizes.put(field.name(), fieldSize);
215+
fieldSizes.put(field.name(), field.size());
214216
});
215217
return fieldSizes;
216218
}
217219

218-
private long getFieldSize(Class<?> fieldType) {
219-
if (fieldType == boolean.class || fieldType == byte.class) {
220-
return 1;
221-
}
222-
if (fieldType == char.class || fieldType == short.class) {
223-
return 2;
224-
}
225-
if (fieldType == int.class || fieldType == float.class) {
226-
return 4;
227-
}
228-
if (fieldType == long.class || fieldType == double.class) {
229-
return 8;
230-
}
231-
return 4; // ссылка
232-
}
233-
234220
private List<FieldAlignmentIssue> findAlignmentIssues(ClassLayout classLayout) {
235221
List<FieldAlignmentIssue> issues = new ArrayList<>();
236222
var layout = classLayout.toPrintable();

0 commit comments

Comments
 (0)