or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

exceptions.mdindex.mdinitialization.mdmemory-management.mdmodules.mdobjects.mdutilities.md

memory-management.mddocs/

0

# Memory Management

1

2

Direct access to Python's memory allocation system and garbage collection functionality. This includes raw memory operations, Python-aware memory allocation, object-specific allocation, and memory allocator management.

3

4

## Capabilities

5

6

### Raw Memory Allocation

7

8

Low-level memory allocation functions similar to C's malloc/free family, without GIL requirements.

9

10

```java { .api }

11

/**

12

* Allocate raw memory block

13

* @param size - Size in bytes to allocate

14

* @return Pointer to allocated memory, or NULL on failure

15

*/

16

public static native Pointer PyMem_RawMalloc(long size);

17

18

/**

19

* Allocate and zero-initialize raw memory block

20

* @param nelem - Number of elements

21

* @param elsize - Size of each element in bytes

22

* @return Pointer to allocated memory, or NULL on failure

23

*/

24

public static native Pointer PyMem_RawCalloc(long nelem, long elsize);

25

26

/**

27

* Resize raw memory block

28

* @param ptr - Pointer to existing memory block (or NULL)

29

* @param new_size - New size in bytes

30

* @return Pointer to resized memory, or NULL on failure

31

*/

32

public static native Pointer PyMem_RawRealloc(Pointer ptr, long new_size);

33

34

/**

35

* Free raw memory block

36

* @param ptr - Pointer to memory to free (NULL safe)

37

*/

38

public static native void PyMem_RawFree(Pointer ptr);

39

```

40

41

**Usage Example:**

42

43

```java

44

import static org.bytedeco.cpython.global.python.*;

45

46

// Allocate raw memory (no GIL required)

47

Pointer buffer = PyMem_RawMalloc(1024);

48

if (buffer != null) {

49

// Use buffer

50

51

// Resize if needed

52

buffer = PyMem_RawRealloc(buffer, 2048);

53

54

// Always free when done

55

PyMem_RawFree(buffer);

56

}

57

```

58

59

### Python Memory Allocation

60

61

Python-aware memory allocation that integrates with the GIL and Python's memory management system.

62

63

```java { .api }

64

/**

65

* Allocate memory using Python's allocator

66

* @param size - Size in bytes to allocate

67

* @return Pointer to allocated memory, or NULL on failure

68

*/

69

public static native Pointer PyMem_Malloc(long size);

70

71

/**

72

* Allocate and zero-initialize memory using Python's allocator

73

* @param nelem - Number of elements

74

* @param elsize - Size of each element in bytes

75

* @return Pointer to allocated memory, or NULL on failure

76

*/

77

public static native Pointer PyMem_Calloc(long nelem, long elsize);

78

79

/**

80

* Resize memory block using Python's allocator

81

* @param ptr - Pointer to existing memory block (or NULL)

82

* @param new_size - New size in bytes

83

* @return Pointer to resized memory, or NULL on failure

84

*/

85

public static native Pointer PyMem_Realloc(Pointer ptr, long new_size);

86

87

/**

88

* Free memory allocated by Python's allocator

89

* @param ptr - Pointer to memory to free (NULL safe)

90

*/

91

public static native void PyMem_Free(Pointer ptr);

92

```

93

94

**Usage Example:**

95

96

```java

97

// Allocate memory (requires GIL)

98

int gilState = PyGILState_Ensure();

99

try {

100

Pointer pythonMem = PyMem_Malloc(512);

101

if (pythonMem != null) {

102

// Use memory for Python-related operations

103

104

// Free when done

105

PyMem_Free(pythonMem);

106

}

107

} finally {

108

PyGILState_Release(gilState);

109

}

110

```

111

112

### Memory Allocator Management

113

114

Functions for managing and configuring Python's memory allocators.

115

116

```java { .api }

117

/**

118

* Get current memory allocator for domain

119

* @param domain - Memory domain (PYMEM_DOMAIN_RAW, PYMEM_DOMAIN_MEM, etc.)

120

* @param allocator - Structure to receive allocator info

121

*/

122

public static native void PyMem_GetAllocator(int domain, PyMemAllocatorEx allocator);

123

124

/**

125

* Set memory allocator for domain

126

* @param domain - Memory domain to configure

127

* @param allocator - New allocator configuration

128

*/

129

public static native void PyMem_SetAllocator(int domain, PyMemAllocatorEx allocator);

130

131

/**

132

* Setup debug hooks for memory allocation

133

*/

134

public static native void PyMem_SetupDebugHooks();

135

```

136

137

### Object Memory Management

138

139

Specialized memory allocation for Python objects and types.

140

141

```java { .api }

142

/**

143

* Generic allocation for Python type instances

144

* @param type - Type to allocate instance of

145

* @param nitems - Number of items (for variable-length objects)

146

* @return New object instance, or NULL on failure

147

*/

148

public static native PyObject PyType_GenericAlloc(PyTypeObject type, long nitems);

149

```

150

151

**Usage Example:**

152

153

```java

154

// Allocate instance of a specific type

155

PyTypeObject listType = PyList_Type(); // Assuming this function exists

156

PyObject newList = PyType_GenericAlloc(listType, 0);

157

158

if (newList != null) {

159

// Initialize the object as needed

160

// Note: Generic allocation may require additional initialization

161

}

162

```

163

164

### Memory Constants and Utilities

165

166

Important constants and utility values for memory operations.

167

168

```java { .api }

169

/**

170

* Immortal reference count value (objects that are never deallocated)

171

*/

172

public static final long _Py_IMMORTAL_REFCNT = _Py_IMMORTAL_REFCNT();

173

174

/**

175

* Invalid size marker

176

*/

177

public static final long Py_INVALID_SIZE = (long)-1;

178

```

179

180

### Memory Allocator Structure

181

182

```java { .api }

183

/**

184

* Memory allocator configuration structure

185

*/

186

class PyMemAllocatorEx extends Pointer {

187

// Contains function pointers for:

188

// - malloc function

189

// - calloc function

190

// - realloc function

191

// - free function

192

// - context pointer for allocator data

193

}

194

```

195

196

## Memory Domains

197

198

Python uses different memory domains for different purposes:

199

200

```java

201

// Memory domain constants (typical values - check actual bindings)

202

public static final int PYMEM_DOMAIN_RAW = 0; // Raw memory (no GIL)

203

public static final int PYMEM_DOMAIN_MEM = 1; // Python memory (with GIL)

204

public static final int PYMEM_DOMAIN_OBJ = 2; // Object memory

205

```

206

207

## Advanced Memory Management Patterns

208

209

### Custom Allocator Setup

210

211

```java

212

import static org.bytedeco.cpython.global.python.*;

213

214

// Get current allocator

215

PyMemAllocatorEx currentAllocator = new PyMemAllocatorEx();

216

PyMem_GetAllocator(PYMEM_DOMAIN_MEM, currentAllocator);

217

218

// Save for restoration later

219

PyMemAllocatorEx savedAllocator = new PyMemAllocatorEx();

220

PyMem_GetAllocator(PYMEM_DOMAIN_MEM, savedAllocator);

221

222

// Set debug allocator

223

PyMem_SetupDebugHooks();

224

225

// ... use Python with debug memory tracking ...

226

227

// Restore original allocator

228

PyMem_SetAllocator(PYMEM_DOMAIN_MEM, savedAllocator);

229

```

230

231

### Memory Usage Monitoring

232

233

```java

234

// Enable debug hooks to track memory usage

235

PyMem_SetupDebugHooks();

236

237

// Allocate some Python objects

238

PyObject list = PyList_New(1000);

239

for (int i = 0; i < 1000; i++) {

240

PyObject item = PyLong_FromLong(i);

241

PyList_SetItem(list, i, item);

242

}

243

244

// Debug hooks will track allocations and detect leaks

245

```

246

247

### Large Memory Allocation

248

249

```java

250

// For large allocations, consider using raw allocator

251

// to avoid GIL overhead

252

long largeSize = 1024 * 1024 * 100; // 100MB

253

254

Pointer largeBuffer = PyMem_RawMalloc(largeSize);

255

if (largeBuffer != null) {

256

try {

257

// Use buffer for bulk operations

258

// Process data without holding GIL unnecessarily

259

260

} finally {

261

PyMem_RawFree(largeBuffer);

262

}

263

}

264

```

265

266

### Memory-Efficient Object Creation

267

268

```java

269

// Pre-allocate containers to avoid repeated reallocations

270

PyObject list = PyList_New(1000); // Pre-size for expected items

271

272

// Use PyList_SET_ITEM for pre-allocated slots (faster)

273

for (int i = 0; i < 1000; i++) {

274

PyObject item = PyLong_FromLong(i);

275

PyList_SET_ITEM(list, i, item); // No bounds checking

276

}

277

```

278

279

## Memory Management Best Practices

280

281

### Choose the Right Allocator

282

283

```java

284

// Use raw allocator for:

285

// - Large temporary buffers

286

// - Non-Python data structures

287

// - Operations without GIL

288

Pointer tempBuffer = PyMem_RawMalloc(bufferSize);

289

290

// Use Python allocator for:

291

// - Python object creation

292

// - Operations requiring GIL

293

// - Memory that may be tracked by Python

294

Pointer pythonBuffer = PyMem_Malloc(bufferSize);

295

```

296

297

### Memory Leak Prevention

298

299

```java

300

Pointer memory = null;

301

try {

302

memory = PyMem_Malloc(1024);

303

if (memory == null) {

304

// Handle allocation failure

305

return;

306

}

307

308

// Use memory

309

310

} finally {

311

// Always free in finally block

312

if (memory != null) {

313

PyMem_Free(memory);

314

}

315

}

316

```

317

318

### Exception Safety

319

320

```java

321

PyObject obj1 = null;

322

PyObject obj2 = null;

323

324

try {

325

obj1 = PyList_New(10);

326

if (obj1 == null || PyErr_Occurred() != null) {

327

throw new RuntimeException("Failed to create list");

328

}

329

330

obj2 = PyDict_New();

331

if (obj2 == null || PyErr_Occurred() != null) {

332

throw new RuntimeException("Failed to create dict");

333

}

334

335

// Use objects

336

337

} catch (Exception e) {

338

// Clean up on exception

339

// Note: In real usage, objects are typically managed

340

// by Python's reference counting system

341

throw e;

342

}

343

```

344

345

### Memory Debugging

346

347

```java

348

// Enable memory debugging

349

PyMem_SetupDebugHooks();

350

351

// Create objects that might leak

352

PyObject potentialLeak = createComplexStructure();

353

354

// Force garbage collection to detect issues

355

System.gc(); // Java GC

356

// Python GC would be triggered through PyRun_SimpleString("import gc; gc.collect()")

357

358

// Debug hooks will report any issues

359

```

360

361

## Integration with Java Memory Management

362

363

### JavaCPP Integration

364

365

The JavaCPP framework automatically manages the lifecycle of native objects:

366

367

```java

368

// JavaCPP handles native memory cleanup

369

PyObject obj = new PyObject() {

370

{

371

// Object initialization

372

}

373

374

@Override

375

public void deallocate() {

376

// Custom cleanup if needed

377

super.deallocate();

378

}

379

};

380

381

// Object will be cleaned up when Java object is GC'd

382

```

383

384

### Cross-Language Memory Considerations

385

386

```java

387

// When passing data between Java and Python:

388

389

// 1. Java -> Python: Copy data or ensure Java object lifetime

390

byte[] javaData = getDataFromJava();

391

Pointer pythonBuffer = PyMem_Malloc(javaData.length);

392

pythonBuffer.put(javaData); // Copy to Python-managed memory

393

394

// 2. Python -> Java: Copy data before Python object is freed

395

PyObject pythonString = getPythonString();

396

String javaString = PyUnicode_AsUTF8(pythonString); // Immediate copy

397

```

398

399

## Important Notes

400

401

### GIL Requirements

402

403

- **Raw allocator functions**: No GIL required, thread-safe

404

- **Python allocator functions**: Require GIL to be held

405

- **Object allocation functions**: Always require GIL

406

407

### Error Handling

408

409

Memory allocation functions return NULL on failure. Always check return values and handle allocation failures gracefully.

410

411

### Platform Considerations

412

413

Memory allocation behavior may vary between platforms. The debug hooks and allocator management functions help ensure consistent behavior across platforms.

414

415

### Performance Considerations

416

417

- Use raw allocators for large temporary buffers

418

- Pre-allocate containers when final size is known

419

- Avoid frequent small allocations - batch operations when possible

420

- Consider memory alignment for performance-critical operations