private void mark() {
		int bitmapSize = (int) (header.root[currIndex].size >>> (dbAllocationQuantumBits + 5)) + 1;
		boolean existsNotMarkedObjects;
		long pos;
		int i, j;

		if (listener != null) {
			listener.gcStarted();
		}

		greyBitmap = new int[bitmapSize];
		blackBitmap = new int[bitmapSize];

		int rootOid = header.root[currIndex].rootObject;

		if (rootOid != 0) {
			markOid(rootOid);

			do {
				existsNotMarkedObjects = false;
				for (i = 0; i < bitmapSize; i++) {
					if (greyBitmap[i] != 0) {
						existsNotMarkedObjects = true;

						for (j = 0; j < 32; j++) {
							if ((greyBitmap[i] & (1 << j)) != 0) {
								pos = (((long) i << 5) + j) << dbAllocationQuantumBits;
								greyBitmap[i] &= ~(1 << j);
								blackBitmap[i] |= 1 << j;

								int offs = (int) pos & (Page.pageSize - 1);
								Page pg = pool.getPage(pos - offs);
								int typeOid = ObjectHeader.getType(pg.data,
										offs);

								if (typeOid != 0) {
									ClassDescriptor desc = findClassDescriptor(typeOid);

									if (Btree.class.isAssignableFrom(desc.cls)) {
										Btree btree = new Btree(pg.data,
												ObjectHeader.sizeof + offs);
										btree.assignOid(this, 0, false);
										btree.markTree();
									}
									else if (desc.hasReferences) {
										markObject(pool.get(pos),
												ObjectHeader.sizeof, desc);
									}
								}

								pool.unfix(pg);
							}
						}
					}
				}
			}
			while (existsNotMarkedObjects);
		}
	}