Thank you for your interest in contributing! This guide will help you extend and improve the heap dump analyser.
- Node.js 18+ and npm
- A text editor (VS Code recommended)
- Git
# Clone the repository
git clone https://github.com/deepwired/java-heap-dump-analyser.git
cd java-heap-dump-analyser
# Install dependencies
npm install
# Start development server
npm start
# In another terminal, run linter
npm run lint
# Build for production
npm run buildjava-heap-dump-analyser/
├── src/
│ ├── components/ # React UI components
│ │ ├── FileUpload.jsx
│ │ ├── HistogramView.jsx
│ │ ├── DominatorTreeView.jsx
│ │ └── LeakSuspectsView.jsx
│ ├── services/ # Business logic
│ │ ├── hprofParser.js # HPROF file parser
│ │ └── analyzers/ # Analysis algorithms
│ │ ├── histogramAnalyzer.js
│ │ ├── dominatorTreeAnalyzer.js
│ │ ├── leakDetector.js
│ │ └── referenceChainAnalyzer.js
│ ├── App.jsx # Main application
│ └── main.jsx # Entry point
├── public/ # Static assets
├── README.md # User documentation
├── TESTING.md # Testing guide
└── package.json # Dependencies
To add a new analyzer (e.g., detect duplicate strings):
- Create
src/services/analyzers/duplicateDetector.js:
/**
* Duplicate String Detector
* Finds duplicate string values that waste memory
*/
export function findDuplicateStrings(heapData) {
const stringValues = new Map(); // value -> count
// Analyze string instances
// ... implementation
return duplicates;
}- Add it to
src/App.jsx:
import { findDuplicateStrings } from './services/analyzers/duplicateDetector.js';
// In handleFileSelect:
const duplicates = findDuplicateStrings(parsedData);
setDuplicates(duplicates);-
Create a UI component
src/components/DuplicatesView.jsx -
Add a new tab in the UI
The parser is in src/services/hprofParser.js. To add support for new record types:
// Add to SUB_TAGS constant
const SUB_TAGS = {
// ... existing tags
NEW_RECORD_TYPE: 0xAB,
};
// Add parser method
parseNewRecordType() {
// Read record data
const data = this.readValue(type);
// Store in appropriate collection
this.newRecords.set(id, data);
}
// Add to parseHeapDump switch statement
case SUB_TAGS.NEW_RECORD_TYPE:
this.parseNewRecordType();
break;Edit src/services/analyzers/leakDetector.js:
// Add new pattern to LEAK_PATTERNS
const LEAK_PATTERNS = {
// ... existing patterns
NEW_PATTERN: {
pattern: /YourPattern/i,
name: 'Pattern Name',
description: 'What this pattern indicates',
severity: 'high'
}
};Components use React hooks and CSS modules. Example:
import { useState, useMemo } from 'react';
import './YourComponent.css';
function YourComponent({ data }) {
const [filter, setFilter] = useState('');
const filtered = useMemo(() => {
return data.filter(item => item.name.includes(filter));
}, [data, filter]);
return (
<div className="your-component">
<input
value={filter}
onChange={e => setFilter(e.target.value)}
/>
{/* ... */}
</div>
);
}- Privacy First: Never make network requests with user data
- Performance: Be mindful of large heap dumps
- Comments: Document complex algorithms
- Error Handling: Always validate and handle errors gracefully
- Use meaningful variable names
- Add JSDoc comments for public functions
- Keep functions small and focused
- Use const/let, avoid var
- Prefer functional patterns over classes
/**
* Calculate retained heap size by class
* @param {Object} heapData - Parsed heap dump data
* @param {Map} heapData.classes - Map of class ID to class info
* @param {Map} heapData.instances - Map of object ID to instance
* @returns {Array<Object>} Array of {className, retainedSize, instanceCount}
*/
export function calculateRetainedHeap(heapData) {
// Implementation
}- Use the test programs in
TESTING.mdto generate heap dumps - Load them in the application
- Verify all tabs work correctly
- Test search, sort, and filter features
npm run lintFix any errors before submitting.
npm run buildEnsure the build succeeds.
For heaps >1GB, consider:
- Streaming Parsing: Parse in chunks instead of loading everything
- Web Workers: Move parsing to a background thread
- IndexedDB: Store parsed data in browser database
- Pagination: Show results in pages
Example worker:
// src/workers/parser.worker.js
import HprofParser from '../services/hprofParser.js';
self.onmessage = async (e) => {
const parser = new HprofParser();
const result = await parser.parse(e.data);
self.postMessage(result);
};For better performance, consider porting the parser to WebAssembly:
- Write parser in Rust/C++
- Compile to WASM
- Create JavaScript bindings
- Fall back to JS parser for compatibility
Consider adding:
- Graph View: Visualize object references as a graph
- Timeline: Show object allocation over time (if dump includes timestamps)
- Heatmap: Visual representation of memory usage
- Diff View: Compare two heap dumps
Libraries to consider:
- D3.js for graphs
- React Flow for interactive diagrams
- Recharts for charts
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes
- Run linter:
npm run lint - Test thoroughly
- Commit with clear messages:
git commit -m "Add feature X" - Push:
git push origin feature-name - Open a Pull Request
- Describe what the PR does
- Explain why the change is needed
- Include screenshots for UI changes
- Reference any related issues
- Ensure CI passes
- Open an issue for bugs or feature requests
- Tag issues with appropriate labels
- Be respectful and constructive
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.
Thank you for helping make this tool better for everyone!